Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Migrating from Pylons 1.0.2

58 views
Skip to first unread message

Milan Kelesi

unread,
Apr 1, 2025, 6:48:01 AMApr 1
to pylons-discuss
Hello,

We are planning to migrate an existing project from Pylons 1.0.2 to Pyramid 2.x.
What would be the best approach to start?
I understand we need to rewrite all the controllers.
We are using Genshi templates and this does not seem to be supported in Pyramid 2. What would be the easiest template engine to migrate to from Genshi (Mako, Jinja2, Chameleon, ..)
Is there an easy way to reuse the existing routes, globals, application setup?
I am currently a bit overwhelmed and not sure where to start.
I would like to get a quick win and get one simple route/controller without authentication to work under pyramid.

Thanks for any advice.

Mike Orr

unread,
Apr 1, 2025, 8:29:17 AMApr 1
to pylons-...@googlegroups.com
Here's the information the Pylons developers and core users at the
time used to migrate their applications to Pyramid.
https://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/pylons/index.html
(Pyramid Cookbook, section "Pyramid for Pylons Users", written by me)
That was in 2012. I migrated my applications later when work resources
allowed, in 2017 and 2020. It was so long ago I'm afraid I don't
remember what Pylons code looks like, or what Genshi was like. We also
made the migration under Python 2, and some of the older tools were
never ported to Python 3.

I'd use the guide as background information to understand Pyramid, and
how certain Pylons features relate to their closest Pyramid
counterparts. I wouldn't use the specific tools mentioned (akhet,
pyramid_sqla) because they were never used much and may no longer
work. If your application uses webhelpers, it has been replaced by
webhelpers2, which has its own migration guide.

Some developer tried to mimic the Pylons application structure as
closely as possible in Pyramid; e.g., using a class for a group of
controllers, but the first real applications to be ported found it
better to switch to the native Pyramid paradigm rather than trying to
recreate a Pylons-like structure, so later conversions also followed
that approach (including mine). So I'd try to rethink your
application's functionality in a native Pyramid paradigm, rather than
trying to replicate a Pylons-like structure. When you can identify
more specific problems (e.g., how to migrate something in a Pylons
controller, or a specific route feature or temilating feature), then
we may be able to help more with those.

Pylons controllers were classes that grouped several view methods
together. I would port each view separately, as either a function or
class (your choice). If you go the class way, you can have a base
class for common functionality. The simplest base class is:

```
class View:
def ___init__(self, request):
self.request = request
```

If you go the function way, you'd put common functionality in utility functions.

There is a Genshi template adapter for Pyramid, 'pyramid_genshi'. I
don't know of anybody who has used it, or whether it still works. Most
Pylons developers migrated to Mako. Jinja2 and Chameleon get some use.

There's no way to reuse existing routes, globals, and application
setup, because those are the things that changed the most in Pyramid.
Pylons had a number of "magic" globals that you imported, and the
value was local to the current request. So you didn't have to pass
those around between functions; you could just import them in each
one. Pylons applications used these extensively, but they proved to be
fragile and to break easily. So most applications migrating to Pyramid
switched to explicit argument passing to eliminate the magic. That's a
large part of why you can't just use globals and setup code in Pyramid
the same way as in Python, and why WebHelpers2 had to restructure or
drop many helpers that WebHelpers had. Pyramid does have a few
"threadlocals" under the hood, but it's not recommended to use those
directly. Most of what in Pylons you'd import a magic global for, in
Pyramid you'd use the 'request' object.

The 'request' object is implicitly passed to templates in case it's
needed for this. E.g., Pyramid's 'request.route_path()' replaces
Pylons' magic 'url()' function. (It wasn't really a function, but
that's how it was used.) You can call that in the tempate, or
precalcuate the URLs in the views and pass them as template variables.
I've grown to prefer the latter, so that if an exception occurs, it
occurs in static Python code in your repository rather than in a
generated Python template module.

I'd follow one of the Pyramid tutorials to create a basic application,
and then try to add one view or feature from your application at a
time.
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/pylons-discuss/5e27e69c-f7b6-47ed-917a-8c66d0537c4dn%40googlegroups.com.



--
Mike Orr <slugg...@gmail.com>

Ian Wilson

unread,
Apr 1, 2025, 10:22:40 AMApr 1
to pylons-...@googlegroups.com
Pretty impressive it is still working.  Is the codebase still using Python 2?

The last page of the document that Mike linked seems like the best starting point: https://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/pylons/migrate.html

I guess it also depends on how many resources you have, how big the code base is and how much downtime is allowable.

A while ago I moved a PHP project into pyramid by running them behind a proxy and moving route by route, or sometimes a subsystem at a time and that went better than expected and was pretty flexible.  Some work had to be done beforehand to make sure both systems were using the sessions, cookie-based, the same way and that the database clients, mysql, were configured the same way, etc.  Sounds complicated but I think you can create a docker-compose setup with nginx+database+app1+app2 set up without doing anything too crazy.  Then just start chunking away at it and still have both systems constantly "runnable" and not half-broken.

Also if you could convert the templates last I would try to do that.  I think Genshi itself is still used by some projects so even if that adapter, `pyramid_genshi`, is out of date you could potentially fix it and keep your templates as-is and just find/simulate and inject any objects that were expected to exist within the templates, ie. https://docs.pylonsproject.org/projects/pylons-webframework/en/latest/modules/templating.html#template-globals
Then you could come back and convert those templates to something else if it was necessary without falling into a total rewrite.

Just me 2 cents.

Sounds kind of exciting to be honest.

Laurent Daverio

unread,
Apr 1, 2025, 1:01:43 PMApr 1
to pylons-...@googlegroups.com
Maybe a little off-topic, but the first idea springing to my mind when I read about converting Genshi templates into something else is "Why not go all the way to front-end development?"

Of course, it would be more work than just migrating to a classic Pyramid app (although the Python part would become much simpler, as complexity is off-loaded to the front-end app), but it's certainly worth it in the end. Personally, I have transitioned to back-end/front-end dev over a few years, it was sometimes tough, but it's done and I'm not looking back :)

- 2 Python packages for the back-end (one "core", which can be shared between all projects, and one "custom"). Pyramid's ability for extending apps is precious here.
- 2 Next.js/React packages for the front-end (one "core", one "custom" - with Yarn workspaces to link the two)
- Ansible scripts to simplify management (deployment, sync db between production/staging/dev sites, ...), as the new architecture is more complex

Just my 2 (Canadian) cents :)

Laurent.

Jonathan Vanasco

unread,
Apr 1, 2025, 1:14:08 PMApr 1
to pylons-discuss
Pyramid offers a few ways to implement the routes/controllers.

The easiest when porting from Pylons is to use classes with @viewconfig, that can mimic the pylons handler classes.

This is a good example of that approach in the regular pyramid docs: https://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/pylons/views.html

Pretty much everything can be supported and migrated with not too much work, except for the globals. IIRC Pylons did some weird stuff with globals that wasn't necessarily threadsafe.  When moving to pyramid you can use events to define/translate "globals" into templates.  For the python code, you can also update code to not use globals and take a context object as the first argument.  The context object could be a request, or an object that wraps a request.  

In terms of templating - if there isn't a genshi package you could probably model one after pyramid_mako and port the pylons package over.  It might be much faster to do that, and then lightly adapt the templates, then reinvent everything.  


Jonathan Vanasco

unread,
Apr 1, 2025, 5:20:03 PMApr 1
to pylons-discuss
i forgot to mention - if your app uses formencode for validation, I ported the pylons validation to pyramid a long time ago and still actively use and maintain it - https://github.com/jvanasco/pyramid_formencode_classic

Mike Orr

unread,
Apr 1, 2025, 6:36:15 PMApr 1
to pylons-...@googlegroups.com
I've been using Formencode throughout for both form validation and
config settings validation. Thanks for porting it to Pyramid and
Python 3 and dealing with changes within Python 3: I remember all of
those broke functionality until Formencode was patched.
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/pylons-discuss/7411399e-9ec1-4411-9e45-5b53fcc823ebn%40googlegroups.com.



--
Mike Orr <slugg...@gmail.com>

Jonathan Vanasco

unread,
Apr 2, 2025, 1:22:13 PMApr 2
to pylons-discuss
I'm actually in the process of new release to fix some issues and simplify the API; I've been dealing with testing and regressions across a handful of deployments for the past week.  I'm nearly there and will finally hit a 1.0 release once this looks good.  There are some breaking changes but the API is significantly simpler and more consistent. I'm just dealing with small issues about handling "special errors" correctly (like controlling how "nothing submitted" is handled).

I just pushed a 0.9.2 release out for testing across some CI systems, and that seems to be the direction things are going in.  I tried a few other minor releases with slightly different breaking changes.

Mike Orr

unread,
Apr 2, 2025, 2:22:31 PMApr 2
to pylons-...@googlegroups.com
I just use the regular Formencode library in Pyramid in case that
wasn't clear. I didn't know about 'pyramid_formencode'.

For the settings I have a Schema. Since setting names have dots in
them I can't use attribute-based definitions, so I do it in init,
setting `self.fields[name] = myvalidator`. My `main()` routine calls a
function `process_settings(settings)` that instantiates the schema,
validates them and coerces their types, and returns the resulting
dict. If they're invalid I get a formencode.Invalid exception. Then I
think I do something to display the invalid settings. I originally had
several settings required, but I'm now moving away from that gradually
to allow an incomplete configuration file, with deployment-specific
values of some "required" settings coming from environment variables.
> To view this discussion visit https://groups.google.com/d/msgid/pylons-discuss/6223811b-7edd-44ad-b5c6-ce92fb135a61n%40googlegroups.com.



--
Mike Orr <slugg...@gmail.com>

Jonathan Vanasco

unread,
Apr 2, 2025, 3:47:16 PMApr 2
to pylons-discuss
ah. I wrote this package to adapt the @validate decorator and form reprint concepts from pylons into pyramid https://github.com/jvanasco/pyramid_formencode_classic

it helped me migrate apps fairly quickly. 

Milan Kelesi

unread,
Jun 6, 2025, 2:32:16 AMJun 6
to pylons-discuss
Hello all,

Thank you for the suggestions, those helped to begin.
Recently we started working on it and some questions popped up.

1. The pylons project uses this middleware wrapper with:
  • routes.middleware - I suppose the routes are handled by pyramid and we don't need this
  • paste - if I understand this correctly, this is obsolete in pyramid?
  • beaker.middleware - Is there a point to use beaker as WSGI middleware in pyramid? 
    • I currently set it up per documentation when setting up the config with session factory:
    • from pyramid_beaker import session_factory_from_settings
      session_factory = session_factory_from_settings(settings)
      config.set_session_factory(session_factory)
2. We have some variables that were set in Pylons as globals and are used almost in all templates.
What is the best way to add these variables to all views or a subset of views without explicitly adding them to every view ? I was looking at tweens or just creating a base class from which the view classes would descend and would inject the variables in returned dictionary.
Maybe there is a better way?

Florian Schulze

unread,
Jun 6, 2025, 2:39:55 AMJun 6
to pylons-discuss
> 2. We have some variables that were set in Pylons as globals and are used
> almost in all templates.
> What is the best way to add these variables to all views or a subset of
> views without explicitly adding them to every view ? I was looking at
> tweens or just creating a base class from which the view classes would
> descend and would inject the variables in returned dictionary.
> Maybe there is a better way?

You can inject variables into the renderer:
https://docs.pylonsproject.org/projects/pyramid/en/2.0-branch/narr/hooks.html#using-the-before-render-event

Or add a method/property to requests:
https://docs.pylonsproject.org/projects/pyramid/en/2.0-branch/api/config.html#pyramid.config.Configurator.add_request_method

There might be other more appropriate methods using other events or hooks depending on your use cases.

Regards,
Florian

Milan Kelesi

unread,
Jun 6, 2025, 2:46:58 AMJun 6
to pylons-discuss
I actually just now found the BeforeRender event, which seems to be what we need :)

Thanks,
Milan

Mike Orr

unread,
Jun 6, 2025, 11:00:02 AMJun 6
to pylons-...@googlegroups.com
On Thu, Jun 5, 2025 at 11:32 PM Milan Kelesi <kel...@gmail.com> wrote:
> beaker.middleware - Is there a point to use beaker as WSGI middleware in pyramid?

I use 'pyramid_session_redis' in some of my applications and
'pyramid_beaker' in others. Beaker has backend for both Redis, other
databases, and non-databases, so it's useful when some deployments are
Redis and others are non-Redis.

For instance, one application runs both on a web server and is
embedded into Electron Windows and Mac desktop applications. The web
deployment uses Redis. The desktop platforms don't have Redis and have
only one user, so they use memory sessions.

Another application, the main developer has a Mac environment without
Redis, so we use file-based sessions there, and Redis on the
webserver. (The Webserver deployment is in Docker with Docker Redis,
while the Mac workstation has a Conda environment (Minoforge) and just
runs 'pserve'.)
Reply all
Reply to author
Forward
0 new messages