Upgrading from earlier versions of Fresco¶
Make sure you read the CHANGELOG before you update your application to a newer version of Fresco.
Fresco releases have version numbers in the form x.y.z. The major version is x.y, and z is the minor version number. Minor releases will be backwards compatible with the previous minor release.
Occasionally features will be deprecated in a new release,
pending later removal.
By default Python does not show DeprecationWarnings
.
To ensure that you see these warnings,
always run your application with python’s -Wd
command line option,
or set the environment variable PYTHONWARNINGS=d
.
Add this line to your shell’s configuration file
(eg .zshrc
or .bashrc
)
to enable this by default:
export PYTHONWARNINGS=d
Upgrading from Pesto¶
Fresco was originally based on the Pesto library. While Fresco is not backwards compatible, it does provide a reasonably straightforward migration path for applications written using Pesto.
Changes to view functions¶
View functions are no longer passed a Request
object
as the first parameter. Therefore it is necessary to remove this from your view
function definitions. Where your views access request
, this must be changed
to context.request
. For example:
def contact_form(request):
send_email(request.get('name'), request.get('message'))
Becomes:
from fresco import context
def contact_form():
request = context.request
send_email(request.get('name'), request.get('message'))
Changes to routing¶
Replace any instances of
DispatcherApp()
withFrescoApp()
Replace
@app.match
calls with@app.route
. For example:
from pesto import DispatcherApp
app = DispatcherApp()
@app.match('/home', 'GET')
...
Becomes:
from fresco import FrescoApp, GET
app = FrescoApp()
@app.route('/home', GET)
...
If you specify multiple HTTP methods in a route, you must now use a list:
@app.match('/form', 'GET', 'POST')
Becomes:
@app.route('/form', [GET, POST])
Changes to URL generation¶
The
urlfor
function is now preferred over the.url
method. Both are supported for the time being, but you should change tourlfor
to guarantee future compatibility.The names of keyword arguments to the
.url
method have also changed and require a leading underscore:myview.url(query={'id': 123})
Becomes:
urlfor(myview, _query={'id': 123})
The following command line should help you track down any calls that need to be changed:s
$ grep -re 'url([^)]*\(query\|script_name\|request\|scheme\|script_name\|fragment\)=' myproject/
The
request
argument may no longer be passed as a positional argument tourl
:myview.url(request)
Becomes:
urlfor(myview, _request=request)
The following command line should help you track down any calls that need to be changed:
$ grep -re 'url(request' myproject/
Changes to middleware configuration¶
You should use the add_middleware
to add the middleware:
app = DispatcherApp()
...
def app_factory(config, **kwargs):
app = mymiddleware(app, 'foo', bar=True)
return app
Becomes:
app = FrescoApp()
def app_factory(config, **kwargs):
app.add_middleware(mymiddleware, 'foo', bar=True)
return app
Changes to the Request object¶
Some property and method names have changed from pesto:
request.request_method
is nowrequest.method
request.request_path
is nowrequest.path
request.request_uri
is nowrequest.url
request.parsed_uri
is nowrequest.parsed_url
request.application_uri
is nowrequest.application_url
request.make_uri
is nowrequest.make_url
The following command line should help you track down any calls that need to be changed:
$ grep -re 'request\.\(request_method\|request_path\|request_uri\|application_uri\|make_uri\)' myproject/
The path_info and script_name arguments of request.make_url should now be upper cased, eg:
request.make_uri(path_info='/')
Becomes:
request.make_url(PATH_INFO='/')
Other changes¶
Change all references to
pesto.currentrequest()
tofresco.currentrequest()
Compatibility shims¶
The code shown below is unsupported and not recommended for anything other than temporary fixes while you migrate a large code base.
Monkey patch pesto.currentrequest
to replace it with fresco’s version:
import pesto
import fresco
pesto.currentrequest = fresco.currentrequest
Adapt pesto DispatcherApp
instances to work in a Fresco application:
from pesto.dispatch import ExtensiblePattern as PestoExtensiblePattern
from fresco.routing import ExtensiblePattern as FrescoExtensiblePattern
from fresco import Route
def pesto_routing_adapter(dispatcher):
"""\
Take a pesto DispatcherApp and adapt routing definitions to the format
required by fresco
"""
dispatcher.__routes__ = []
for pattern, predicate, methods in dispatcher.patterns:
if isinstance(pattern, PestoExtensiblePattern):
pattern = FrescoExtensiblePattern(pattern.pattern,
name=pattern.name)
for m, func in methods.items():
dispatcher.__routes__.append(Route(pattern, m, func,
predicate=predicate))
return dispatcher
app = FrescoApp()
app.include('', pesto_routing_adapter(my_dispatcher_app)
Preserve request object API compability by substituting a hybrid request class that also inherits from the (largely compatible) pesto request class:
from fresco.request import Request as FrescoRequest
from pesto.request import Request as PestoRequest
import fresco
class FrankenRequest(FrescoRequest, PestoRequest):
pass
app = FrescoApp()
app.request_class = FrankenRequest