forked from GoogleCloudPlatform/webapp2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CHANGES
631 lines (452 loc) · 23 KB
/
CHANGES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
Version 2.5.1 - February 07, 2012
---------------------------------
- Bug fix release related to request charset in old versions of
WebOb.
Version 2.5 - February 01, 2012
-------------------------------
Version 2.4 - January 23, 2012
------------------------------
- Maintenance release. Fixed outstanding bugs related to App Engine.
- Removed webapp2_extras/protorpc, broken since webapp2 was added
to App Engine.
Version 2.3 - August 24, 2011
-----------------------------
- webapp2.Response.out creates a reference loop that impedes garbage
collection. Changing it to a property fixed this (Issue #15).
- webapp2_extras.i18n:
- When in debug mode, translations are not cached, so compiling new
translations make them readily available (Issue #13).
- webapp2_extras.auth:
- ATTENTION: auth_id is no longer converted to lower case to retrieve
a key or save a new user in webapp2_extras.appengine.auth.models.User.
This is a more general approach, as not all systems use case-insensitive
user ids. If you want case-insensitive auth ids, convert them to lower
case before passing auth ids to the auth module (Issue #14).
- If user data is missing attributes, don't raise AssertionError.
Simply don't save or return a valid session, instead.
- call user_model.get_id() instead of the ndb-specific user.key.id().
- removed set_password_validator() and set_token_validator().
They add complexity to the API without a use case to justify.
Extend AuthStore to achieve the same thing.
Version 2.2.3 - August 6, 2011
------------------------------
- Version 2.2.2 missed the webapp2_extras.appengine package.
- get_app() and get_request() now test that app and request are set, to avoid
hard to debug stack traces when they are not and the local proxy is used.
Version 2.2.2 - August 5, 2011 (more 2's than ever!)
----------------------------------------------------
- A default charset is always set in the Request object: if it is not defined
in the constructor, environ['CONTENT_TYPE'] is checked; and if it is still
not defined 'utf-8' is used.
- Added token_model as an attribute of the User model; it is used instead of
the hardcoded class.
Version 2.2.1 - August 1st, 2011
--------------------------------
- Fixed a bug in WSGIApplication.run() when running outside of App Engine:
CGIHandler().run(app) -> CGIHandler().run(self). (issue 9)
Version 2.2 - July 30, 2011
===========================
- Revised webapp2_extras.auth and simplified User model, by Kyle Finley.
Thanks!
Version 2.1 - July 29, 2011
===========================
- Added webapp2_extras.auth: high-level utilities for authentication and
authorization.
- Added webapp2_extras.appengine.auth.models: default model implementations
for webapp2_extras.auth (can be overridden).
- Added webapp2_extras.appengine.ndb.unique_model: a model to store unique
values. This was added mainly so that the default user model can have
multiple unique properties.
- import_string() now displays useful debug information when it fails.
- To make things clearly separated specially for those using webapp2
outside of App Engine, from now on all App Engine-specific modules will
be placed in webapp2_extras.appengine. Also three modules were moved to
the new package:
- webapp2_extras.sessions_memcache
- webapp2_extras.sessions_ndb
- webapp2_extras.users
The original modules were not removed, though: they will be kept in the same
place for compatibility purposes, just importing their stuff from the new
locations.
- Config.load_config() now makes a copy of the configuration when user_values
are passed. That keyword is meant to override app configuration, so the
previous behavior was actually wrong. This is a side feature not used inside
webapp2 or even well documented so the change should not affect existing
apps.
Version 2.0.2 - July 18, 2011
=============================
- cached_property now uses threading.RLock for thread-safety.
Version 2.0.1 - July 17, 2011
=============================
- Little fix: use google.appengine.ext.webapp.util if available, like before.
Version 2.0 - July 17, 2011
===========================
- Added support for the (not yet released) App Engine Python 2.7 SDK.
- Deprecated webapp2_extras.local_app. WSGIApplication is now thread-safe
by default when webapp2_extras.local is available.
webapp2_extras.local_app.WSGIApplication can still be imported, but it is
just an alias to webapp2.WSGIApplication (and a deprecation warning is
emitted when it is imported).
- Like DomainRoute, PathPrefixRoute now only tests the nested routes if the
prefix matches. So now it is not only convenient but matches smartly and
faster. ;)
- Added webapp2_extras.security, with security related helpers such as secure
password hashing tools.
- webapp2_extras.sessions:
- Now uses webapp2_extras.security.create_token() to generate session IDs
instead of uuid.
- Added 'backends' configuration: get_session() can now be called passing
a more convenient 'backend' key. Default ones are 'securecookie',
'datastore' and 'memcache'.
- get_build_routes() now yields (name, route) instead of simply route. This
will allow routes with nested routes to act as a proxy to build URIs.
- webapp2.urlunsplit() was removed from the public API.
- Variables names in routes must now look like python identifiers -
this means that they can no longer start with a number, like before.
- Removed support for _anchor in uri_for() -- the documented keyword is
_fragment.
- Removed support for handler functions receiving (request, response). The
correct arguments for function handlers are (request, *args, **kwargs).
- webapp2_extras.json:
- Fixed an issue with importing json on non-GAE environments (missing
absolute import).
- Now imports simplejson directly instead of using the one from Django,
since it is now included in the App Engine SDK (since version 1.4.2).
- Added WSGIApplication.clear_globals(). Instead of
app.set_globals(app=None, request=None), use app.clear_globals().
Version 1.8.1 - June 29, 2011
=============================
- Implemented an adapter mechanism to dispatch different kind of handlers:
webapp.RequestHandler, webapp2.RequestHandler and "view functions".
Instead of monkeypatching handlers (adding a 'factory' attribute),
handlers are wrapped by adapters that do the appropriate dispatch.
How handlers are adapted can be overridden using the convenience method
``set_adapter()`` from the Router class, but the common cases are covered.
- Function views now conveniently receive (request, *args, **kwargs), like
in Django. The previous arguments will work, but they are now deprecated
and will not be supported in the future. This is a major incompatibility
with previous versions but it feels a lot better than the previous
(request, response) behavior, as adapters make it easy to have custom
dispatch arguments using a unified API.
The webapp2.RequestHandler class remain unchanged and is instantiated with
(request, response).
Version 1.8 - June 26, 2011
===========================
- webap2_extras.i18n: the functions passed to I18nStore.set_locale_selector()
and I18nStore.set_timezone_selector() now receive (store, request) instead of
(request, store), for consistency with the router custom callables.
- webap2_extras.json:
- json is imported first trying direct simplejson, then built-in json
(for Python >= 2.6), then the one from django.utils (for App Engine).
- All convenience functions now receive *args, **kwargs to be passed to
encode()/decode().
- Added webapp2_extras.mako.
- Added webapp2.redirect_to.
- Added Request.blank() parameters compatible with WebOb >= 1.0: POST and
**kwargs.
- Increased compatibility with wsgiref.headers.Headers, used by
webapp.Response.
Version 1.7.5 - June 20, 2011
=============================
- Implemented methods from ``wsgiref.headers.Headers``, used by
webapp.Response.headers.
Version 1.7.4 - June 19, 2011
=============================
- Fixed bug in response.status_message.
Version 1.7.3 - June 17, 2011
=============================
- Routes can now only match specific schemes, e.g., 'http' or 'https'.
- Added a tutorial to use webapp2 outside of App Engine.
Version 1.7.2 - June 16, 2011
=============================
- Response is now compatible with latest WebOb.
- Increased Response compatibility with webapp, implementing wsgi_write() and
has_error().
- Changed some status messages to be the same as webapp:
- 203: 'Non-Authoritative Information'
- 302: 'Moved Temporarily'
- 306: 'Unused'
- 408: 'Request Time-out'
- 414: 'Request-URI Too Large'
- 504: 'Gateway Time-out'
- 505: 'HTTP Version not supported'
- Copied Request from webapp, so that when using webapp2 outside of the SDK
they are the same.
- Routes now match the Request path unquoted. See App Engine issue #2636
for an explanation.
Version 1.7.1 - June 14, 2011
=============================
- Added standalone redirect() function.
- RequestHandler.redirect and redirect_to now return a response object.
- Fixed: multiple routes that define methods are tried before MethodNotAllowed
is raised.
- Updated webapp2_extras.protorpc to work with latest ProtoRPC.
Version 1.7 - June 4, 2011
==========================
- Added a simple configuration object for WSGIapplication, available in the
config attribute. Extras modules that use configuration (i18n, jinja2,
sessions) don't require app.config to be set manually anymore. Still, the
`secret_key` key config for sessions, if not defined, will result in an
exception.
- Deprecated webapp2_extras.config, replaced by the simpler app dict.
- Router no longer receives app on construction, for consistency with the
config object. App is set as global before router is initialized.
- Fixed a bug in webapp2_extras.sessions that made it not save the session
when it was empty (like when flashes are popped).
- Added standalone uri_for function, to be used in templates.
Version 1.6.3 - June 3, 2011
============================
- Added webapp2_extras.local_app, with the WSGIApplication previously in
webapp2_extras.local. This allows using LocalProxy on App Engine, without
actually monkeypatching the WSGI app for threaded environments.
- Route now raises exc.HTTPMethodNotAllowed if methods are set and the request
method doesn't match.
- Router.default_matcher() now raises exc.HTTPNotFound if no route matches.
Version 1.6.2 - May 30, 2011
============================
- WSGIApplication.__call__ checks if the dispatcher didn't return None to
accept the returned value as a response. Previously it checked if it was an
instance of Response.
- To support returned response, RequestHandler.dispatch() returns the result of
the dispatched method.
Version 1.6.1 - May 30, 2011
============================
- Fixed an indentation bug in webapp2_extras.users.
- Added back _to_utf8() to convert values for import_string() and urlunsplit().
- Added WSGIApplication.get_response(), a convenience for unit tests.
Version 1.6 - May 29, 2011
==========================
- Handlers registered in WSGIApplication.error_handlers can now also be a
string to be lazily imported.
- The request object now has the active response available as an attribute:
request.response.
- Added a factory method to RequestHandler, to better deal with libraries that
use a custom webapp.RequestHandler constructors (like ProtoRPC).
- Added set_dispatcher() to Router, to set extended dispatching.
- Handlers and error handlers can now return a response object, which will be
used instead of the default response created by the WSGI app. This allows
webapp2 to be used following the common pattern of handlers that return a
response, instead of the webapp way of a handler that writes to an existing
response.
- Request.Handler.redirect() now can receive a `code` parameter, to set the
status code. This is preferable than the `permanent` parameter, kept for
compatibility with webapp.
- webapp2 is now a file webapp2.py, instead of a package with a __init__.py
file.
- API cleanup:
- Removed WSGIApplication.url_for(), to_unicode(), to_utf8().
- RequestHandler.url_for was renamed to uri_for, with url_for kept
as an alias.
- Renamed webapp2_extras.routes.ImprovedRoute to RedirectRoute, as it
basically adds redirect conveniences.
- For consistency with uri building parameters, RedirectHandler parameters
are now prefixed with a underscore: `url` becomes `_uri` and `permanent`
becomes `_permanent`. A parameter `_code` was added to set status code.
- Router.do_match and do_build renamed to default_matcher and
default_dispatcher.
- URI building accepts a _fragment argument, with _anchor as fallback.
Version 1.5 - May 16, 2011
==========================
- Added webapp2_extras.local, with an extended WSGIApplication that uses
thread-local for globals and so can be used outside of App Engine.
- Added webapp2_extras.protorpc, with support for Google ProtoRPC.
- Added set_matcher() and set_builder() to Router, to set extended matcher and
builder.
- Routes now return the route on match() or routes with nested routes cannot
work. So instead of returning (args, kwargs) they return
(route, args, kwargs).
- Now handlers only receive **args if no named variables are set. Otherwise,
they only receive **kwargs. This allows users to use regexes that are not
intended to be captured, mixing named and unnamed variables.
- DomainRoute now uses the same syntax used by webapp2.Route, instead of a
regex. The resulting keywords are added to the mathed route **kwargs.
This gives control of what is passed to the handler if a domain/subdomain
matches, and allows to not pass anything if no regex groups are defined.
- Several small bugs fixed and increased test coverage in webapp2_extras.
Version 1.3 - May 9, 2011
=========================
- Added webapp2_extras modules:
- webapp2_extras.i18n: internationalization support.
- webapp2_extras.sessions_memcache: memcache based sessions.
- webapp2_extras.sessions_ndb: datastore based sessions.
- Several api improvements in webapp2_extras.
Version 1.2 - May 6, 2011
=========================
- Removed Config from webapp2 core. It is now part of the new "webapp2_extras"
package.
- Added the package webapp2_extras. These are all optional modules that
complement webapp2 with common functionalities. Currently they include:
- webapp2_extras.config: Configuration object.
- webapp2_extras.jinja2: Support for Jinja2 templating.
- webapp2_extras.json: JSON utilities.
- webapp2_extras.routes: Extended route classes.
- webapp2_extras.securecookie: Signed cookie serializer.
- webapp2_extras.sessions: Sessions support.
Version 1.1 - May 5, 2011
=========================
- Simplified routing with an unified dispatch method for classes and functions.
Version 1.0 - May 1st, 2011
===========================
This is a major refactoring with some incompatible changes, mostly internal
stuff that won't be noticed in common usage.
- Changed signature of RequestHandler's constructor: it now receives only
(request, response) instead of (app, request, response).
- Added RequestContext class, which should help testing.
- Added .app attribute to Request, a reference to the active app.
- Refactored routing scheme:
- Now also supports function views besides classes.
- Now also supports normal functions as exception handlers, and exception
handlers don't need to be a subclass RequestHandler (but still can).
- Now also supports custom handler methods besides using the request method.
- Removed Request.context: was redundant with Request.registry.
- Renamed WSGIApplication.wsgi_app to WSGIApplication.dispatch.
- Moved ALLOWED_METHODS to WSGIApplication.allowed_methods.
- Moved get_valid_methods() to RequestHandler.get_valid_methods().
Version 0.7 - September 26, 2010
================================
- Added WSGIApplication.app and WSGIApplication.request, class attributes set
on each request to reference currently active app and request.
WSGIApplication.app is an alias to WSGIApplication.active_instance.
- Fixed double escaping of + in urlunsplit(). Thanks, alkis.
- IMPROVED: configuration now behaves exactly like a dictionary, still
auto-loading configuration values when needed and honoring required configs.
For example, we always used this::
bar = self.app.get_config('foo', 'bar')
Now it is also possible to use direct access and dict methods::
bar = self.app.config['foo']['bar']
# or...
bar = self.app.config['foo'].get('bar')
# or...
bar = self.app.config.get('foo').get('bar')
The previous get_config() method works as always.
Version 0.6 - August 31, 2010
=============================
- Fix: Anchors in generated URLs are quoted using urlib.quote, instead of
urlib.quote_plus.
- In Router.dispatch(), if an exception occurs while handling an exception,
raise it instead of trying to handle it again.
- Fixed bug when writing a unicode string to Response and charset is not set.
Thanks to martinc for the patch.
- Changed: the app won't fallback anymore to the exception handler set for
status 500 if handlers for other status are not set.
- Changed: exceptions are only logged when unhandled. It is up to exception
handlers to log them when appropriate.
Version 0.5.1 - August 17, 2010
===============================
- When a URL matches, some attributes are set in the request object:
- request.route: the matched route
- request.route_args: the matched positional arguments, a tuple
- request.route_kwargs: the matched keyword arguments, a dict
- WSGIApplication.handle_exception() doesn't automatically raises the exception
when in debug mode: it is up to the error handler to raise it if in dev; it
will be raised if no error handler is defined to handle it anyway.
- Added attributes, WSGIApplication.registry, Request.registry and
Request.context, dictionaries for objects in use during the app or request
lifetimes.
- Before passing the request method to the RequestHandler, '-' is replaced
by '_', so that a method like WebDav's 'VERSION-CONTROL' can be supported.
- Config.get() now only returns the passed default value when key is defined.
This is the intended, more predictable behavior: default is a default for
the key, not the module. For example::
# If config['foo']['bar'] is not set, return 'baz'.
config.get('foo', 'bar', default='baz')
# If config['foo'] is not set, return None. Default is ignored here.
config.get('foo', default='baz')
- Router initialization now receives the app as parameter, so that extended
routes can access app's config.
Version 0.5 - August 13, 2010
=============================
- Better compatibility with webapp:
- webapp2.WSGIapplication can be used with webapp.RequestHandler.
- webapp.WSGIapplication can be used with webapp2.RequestHandler.
Although the functionality becomes limited in both cases, this should help
migration.
- Review of Response based on observations from
http://pythonpaste.org/webob/differences.html#webapp-response:
- Response.out is now a reference to self, to use webob.Response's neat
.write() method which can handle both string and unicode.
- Response.clear() now sets .body = '' instead of .app_iter = [].
- Added Response.write(), for compatibility with StringIO behavior in webapp
when calling write() passing non-basestring values (issue 2).
- Removed url_escape() and url_unescape(). Unused or almost unused.
- ErrorHandlers can now be defined as strings to be lazily loaded, as they
now use the same dispatch mechanism of other handlers.
Backwards compatibility warning
-------------------------------
- The method handle_exception() is called from app-wide error handlers.
Previously, get() was called.
Version 0.4.1 - August 08, 2010
===============================
- Removed router parameter from get_routes(), get_match_routes(),
get_build_routes(). This simplifies multi-routes quite a bit.
Version 0.4 - August 07, 2010
=============================
- redirect() and redirect_to() now accept a keyword argument 'abort' to raise
an exception to do the redirect.
- '_netloc' can be passed to url_for() build URLs for a given domain or
subdomain.
- Added BaseRoute, an interface for custom routes. Several improvements make
the routing system more extensible, while the default Route class sticks to
the basics.
- Nested routes are now possible. As an example, `extras/routes.py` has several
classes that accept nested routes or extend routing in other ways:
- PathPrefixRoute: the idea of this route is to set a base path for other
routes::
app = WSGIApplication([
PathPrefixRoute('/users/<user:\w+>', [
Route('/', UserOverviewHandler, 'user-overview'),
Route('/profile', UserProfileHandler, 'user-profile'),
Route('/projects', UserProjectsHandler, 'user-projects'),
]),
])
The example above is the same as setting the following routes, just more
convenient as you can reuse the path prefix::
app = WSGIApplication([
Route('/users/<user:\w+>/', UserOverviewHandler, 'user-overview'),
Route('/users/<user:\w+>/profile', UserProfileHandler, 'user-profile'),
Route('/users/<user:\w+>/projects', UserProjectsHandler, 'user-projects'),
])
- NamePrefixRoute: Same as PathPrefixRoute, but prefixes the names of routes.
- HandlerPrefixRoute: Same as PathPrefixRoute, but prefixes the handlers of
routes.
- DomainRoute: a route used to restrict route matches to a given domain or
subdomain.
For example, to restrict routes to a subdomain of the appspot domain::
SUBDOMAIN_RE = '^([^.]+)\.app-id\.appspot\.com$'
app = WSGIApplication([
DomainRoute(SUBDOMAIN_RE, [
Route('/foo', 'FooHandler', 'subdomain-thing'),
]),
Route('/bar', 'BarHandler', 'normal-thing'),
])
- ImprovedRoute: a route with redirect_to and strict_slash.
- `redirect_to`: if set, the route is used to redirect to a URL. The value
can be a URL string or a callable that returns a URL. These two are
equivalent::
route = Route('/foo', RedirectHandler, defaults={'url': '/bar'})
route = Route('/foo', redirect_to='/bar')
- `strict_slash`: if True, redirects access to the same URL with different
trailing slash to the strict path defined in the rule. For example, take
these rules::
route = Route('/foo', FooHandler, strict_slash=True)
route = Route('/bar/', BarHandler, strict_slash=True)
Because **strict_slash** is True, this is what will happen:
- Access to ``/foo`` will execute ``FooHandler`` normally.
- Access to ``/bar/`` will execute ``BarHandler`` normally.
- Access to ``/foo/`` will redirect to ``/foo``.
- Access to ``/bar`` will redirect to ``/bar/``.
Version 0.3 - August 05, 2010
=============================
- Routes store the handler, as we had in 0.1. This allows custom routes to
have nested routes.
- Much improved URL building, now delegated to routes.
- added urlunsplit() helper.
Version 0.2 - August 04, 2010
=============================
- Fixed a bug in Route.match() that would make it return positional arguments
with wrong order. Dictionary is correctly sorted now.
- Added build_only option for routes: routes that are only used for url_for()
and never match.
Version 0.1 - August 03, 2010
=============================
- Initial release.