Release Notes and Changelog¶
Release 0.13¶
Warning
Not released yet.
Dropped support for Python versions that reached their end-of-life.
Keeping up support for ancient Python versions hinders adaptation of new features and serves no real purpose. If you need support for older Python versions, you can stay on bottle-0.12. The updated list of tested and supported python releases is as follows:
- Python 2.7 (>= 2.7.3)
- Python 3.6
- Python 3.7
- Python 3.8
- Python 3.9
- PyPy 2.7
- PyPy 3.6
- PyPy 3.7
Support for Python 2.5 was marked as deprecated since 0.12. We decided to go a step further and also remove support for 2.6 and 3.1 to 3.5 even if it was never deprecated explicitly in bottle. This means that this release is not backwards compatible in Python <2.7.3 or <3.6 environments. Maintainers for distributions or systems that still use these old python versions should not update to Bottle 0.13 and stick with 0.12 instead.
Stabilized APIs
- The documented API of the
ConfigDict
class is now considered stable and ready to use.
Deprecated APIs
- The old route syntax (
/hello/:name
) is deprecated in favor of the more readable and flexible/hello/<name>
syntax. Bottle.mount()
now recognizes Bottle instance and will warn about parameters that are not compatible with the new mounting behavior. The old behavior (mount applications as WSGI callable) still works and is used as a fallback automatically.- The undocumented
local_property()
helper is now deprecated. - The server adapter for google app engine is not useful anymore and marked as deprecated.
- Bottle uses pickle to store arbitrary objects into signed cookies. This is safe, as long as the signature key remains a secret. Unfortunately, people tend to push code with signature keys to github all the time, so we decided to remove pickle-support from bottle. Signed cookies will now issue a deprecation warning if the value is not a string, and support for non-string values will be removed in 0.14. The global
cookie_encode()
,cookie_decode()
andis_cookie_encoded()
are now also deprecated. If you are using this feature, think about using json to serialize your objects before storing them into cookies, or switch to a session system that stores data server-side instead of client-side.
Removed APIs (deprecated since 0.12)
- Plugins with the old API (
api=1
or no api attribute) will no longer work. - Parameter order of
Bottle.mount()
changed in 0.10. The old order will now result in an error instead of a warning. - The
ConfigDict
class was introduced in 0.11 and changed during 0.12. These changes are now final.- Attribute access and assignment was removed due to high overhead and limited usability.
- Namespaced sub-instance creation was removed.
config["a"]["b"]
has a high overhead and little benefit overconfig["a.b"]
. ConfigDict
instances are no longer callable. This was a shortcut forConfigDict.update()
.ConfigDict
constructor no longer accepts any parameters. Use the load_* methods instead.
- Bottle 0.12 changed some aspects of the Simple Template Engine. These changes are now final and the old syntax will now longer work.
- The magic
{{rebase()}}
call was replaced by abase
variable. Example:{{base}}
- In STPL Templates, the ‘rebase’ and ‘include’ keywords were replaced with functions in 0.12.
- PEP-263 encoding strings are no longer recognized. Templates are always utf-8.
- The magic
- The ‘geventSocketIO’ server adapter was removed without notice. It did not work anyway.
Changes
These changes might require special care when updating.
- Signed cookies now use a stronger HMAC algorithm by default. This will result in old cookies to appear invalid after the update. Pass an explicit
digestmod=hashlib.md5
toRequest.get_cookie()
andResponse.set_cookie()
to get the old behavior.
Other Improvements
- Bottle() instances are now context managers. If used in a with-statement, the default application changes to the specific instance and the shortcuts for many instance methods can be used.
- Added support for
PATCH
requests and theBottle.patch()
decorator. - Added aiohttp and uvloop server adapters.
- Added command-line arguments for config from json or ini files.
Bottle.mount()
now recognizes instances ofBottle
and mounts them with significantly less overhead than other WSGI applications.- The
Request.json
property now acceptsapplication/json-rpc
requests. static_file()
gained support forETag
headers. It will generate ETags and recognizesIf-None-Match
headers.- Jinja2 templates will produce better error messages than before.
Release 0.12¶
- New SimpleTemplate parser implementation
- Support for multi-line code blocks (<% … %>).
- The keywords include and rebase are functions now and can accept variable template names.
- The new
BaseRequest.route
property returns theRoute
that originally matched the request. - Removed the
BaseRequest.MAX_PARAMS
limit. The hash collision bug in CPythons dict() implementation was fixed over a year ago. If you are still using Python 2.5 in production, consider upgrading or at least make sure that you get security fixed from your distributor. - New
ConfigDict
API (see Configuration (DRAFT))
More information can be found in this development blog post.
Release 0.11¶
- Native support for Python 2.x and 3.x syntax. No need to run 2to3 anymore.
- Support for partial downloads (
Range
header) instatic_file()
. - The new
ResourceManager
interface helps locating files bundled with an application. - Added a server adapter for waitress.
- New
Bottle.merge()
method to install all routes from one application into another. - New
BaseRequest.app
property to get the application object that handles a request. - Added
FormsDict.decode()
to get an all-unicode version (needed by WTForms). MultiDict
and subclasses are now pickle-able.
API Changes
Response.status
is a read-write property that can be assigned either a numeric status code or a status string with a reason phrase (200 OK
). The return value is now a string to better match existing APIs (WebOb, werkzeug). To be absolutely clear, you can use the read-only propertiesBaseResponse.status_code
andBaseResponse.status_line
.
API Deprecations
SimpleTALTemplate
is now deprecating. There seems to be no demand.
Release 0.10¶
- Plugin API v2
- To use the new API, set
Plugin.api
to2
. Plugin.apply()
receives aRoute
object instead of a context dictionary as second parameter. The new object offers some additional information and may be extended in the future.- Plugin names are considered unique now. The topmost plugin with a given name on a given route is installed, all other plugins with the same name are silently ignored.
- To use the new API, set
- The Request/Response Objects
- Added
BaseRequest.json
,BaseRequest.remote_route
,BaseRequest.remote_addr
,BaseRequest.query
andBaseRequest.script_name
. - Added
BaseResponse.status_line
andBaseResponse.status_code
attributes. In future releases,BaseResponse.status
will return a string (e.g.200 OK
) instead of an integer to match the API of other common frameworks. To make the transition as smooth as possible, you should use the verbose attributes from now on. - Replaced
MultiDict
with a specializedFormsDict
in many places. The new dict implementation allows attribute access and handles unicode form values transparently.
- Added
- Templates
- Added three new functions to the SimpleTemplate default namespace that handle undefined variables:
stpl.defined()
,stpl.get()
andstpl.setdefault()
. - The default escape function for SimpleTemplate now additionally escapes single and double quotes.
- Added three new functions to the SimpleTemplate default namespace that handle undefined variables:
- Routing
- A new route syntax (e.g.
/object/<id:int>
) and support for route wildcard filters. - Four new wildcard filters: int, float, path and re.
- A new route syntax (e.g.
- Other changes
- Added command line interface to load applications and start servers.
- Introduced a
ConfigDict
that makes accessing configuration a lot easier (attribute access and auto-expanding namespaces). - Added support for raw WSGI applications to
Bottle.mount()
. Bottle.mount()
parameter order changed.Bottle.route()
now accepts an import string for thecallback
parameter.- Dropped Gunicorn 0.8 support. Current supported version is 0.13.
- Added custom options to Gunicorn server.
- Finally dropped support for type filters. Replace with a custom plugin of needed.
Release 0.9¶
Whats new?
- A brand new plugin-API. See Plugins and Plugin Development Guide for details.
- The
route()
decorator got a lot of new features. SeeBottle.route()
for details. - New server adapters for gevent, meinheld and bjoern.
- Support for SimpleTAL templates.
- Better runtime exception handling for mako templates in debug mode.
- Lots of documentation, fixes and small improvements.
- A new
Request.urlparts
property.
Performance improvements
- The
Router
now special-caseswsgi.run_once
environments to speed up CGI. - Reduced module load time by ~30% and optimized template parser. See 8ccb2d, f72a7c and b14b9a for details.
- Support for “App Caching” on Google App Engine. See af93ec.
- Some of the rarely used or deprecated features are now plugins that avoid overhead if the feature is not used.
API changes
This release is mostly backward compatible, but some APIs are marked deprecated now and will be removed for the next release. Most noteworthy:
- The
static
route parameter is deprecated. You can escape wild-cards with a backslash. - Type-based output filters are deprecated. They can easily be replaced with plugins.
Release 0.8¶
API changes
These changes may break compatibility with previous versions.
- The built-in Key/Value database is not available anymore. It is marked deprecated since 0.6.4
- The Route syntax and behaviour changed.
- Regular expressions must be encapsulated with
#
. In 0.6 all non-alphanumeric characters not present in the regular expression were allowed. - Regular expressions not part of a route wildcard are escaped automatically. You don’t have to escape dots or other regular control characters anymore. In 0.6 the whole URL was interpreted as a regular expression. You can use anonymous wildcards (
/index:#(\.html)?#
) to achieve a similar behaviour.
- Regular expressions must be encapsulated with
- The
BreakTheBottle
exception is gone. UseHTTPResponse
instead. - The
SimpleTemplate
engine escapes HTML special characters in{{bad_html}}
expressions automatically. Use the new{{!good_html}}
syntax to get old behaviour (no escaping). - The
SimpleTemplate
engine returns unicode strings instead of lists of byte strings. bottle.optimize()
and the automatic route optimization is obsolete.- Some functions and attributes were renamed:
Request._environ
is nowRequest.environ
Response.header
is nowResponse.headers
default_app()
is obsolete. Useapp()
instead.
- The default
redirect()
code changed from 307 to 303. - Removed support for
@default
. Use@error(404)
instead.
New features
This is an incomplete list of new features and improved functionality.
- The
Request
object got new properties:Request.body
,Request.auth
,Request.url
,Request.header
,Request.forms
,Request.files
. - The
Response.set_cookie()
andRequest.get_cookie()
methods are now able to encode and decode python objects. This is called a secure cookie because the encoded values are signed and protected from changes on client side. All pickle-able data structures are allowed. - The new
Router
class drastically improves performance for setups with lots of dynamic routes and supports named routes (named route + dict = URL string). - It is now possible (and recommended) to return
HTTPError
andHTTPResponse
instances or other exception objects instead of raising them. - The new function
static_file()
equalssend_file()
but returns aHTTPResponse
orHTTPError
instead of raising it.send_file()
is deprecated. - New
get()
,post()
,put()
anddelete()
decorators. - The
SimpleTemplate
engine got full unicode support. - Lots of non-critical bugfixes.
Contributors¶
Bottle is written and maintained by Marcel Hellkamp <marc@bottlepy.org>.
Thanks to all the people who found bugs, sent patches, spread the word, helped each other on the mailing-list and made this project possible. I hope the following (alphabetically sorted) list is complete. If you miss your name on that list (or want your name removed) please tell me or add it yourself.
- acasajus
- Adam R. Smith
- Alexey Borzenkov
- Alexis Daboville
- Anton I. Sipos
- Anton Kolechkin
- apexi200sx
- apheage
- BillMa
- Brad Greenlee
- Brandon Gilmore
- Branko Vukelic
- Brian Sierakowski
- Brian Wickman
- Carl Scharenberg
- Damien Degois
- David Buxton
- Duane Johnson
- fcamel
- Frank Murphy
- Frederic Junod
- goldfaber3012
- Greg Milby
- gstein
- Ian Davis
- Itamar Nabriski
- Iuri de Silvio
- Jaimie Murdock
- Jeff Nichols
- Jeremy Kelley
- joegester
- Johannes Krampf
- Jonas Haag
- Joshua Roesslein
- Judson Neer
- Karl
- Kevin Zuber
- Kraken
- Kyle Fritz
- m35
- Marcos Neves
- masklinn
- Michael Labbe
- Michael Soulier
- Nicolas Vanhoren
- Oz N Tiram
- Robert Rollins
- rogererens
- rwxrwx
- Santiago Gala
- Sean M. Collins
- Sebastian Wollrath
- Seth
- Sigurd Høgsbro
- Stuart Rackham
- Sun Ning
- Tomás A. Schertel
- Tristan Zajonc
- voltron
- Wieland Hoffmann
- zombat
- Thiago Avelino