On Mon, 2025-11-10 at 14:03 +0100, Thomas Goirand wrote:
On 11/3/25 5:39 PM, Stephen Finucane wrote:
o/
I'd like to propose the creation of a new "oslo.wsgi" project that service projects should adopt, where it makes sense to. My reasons for this proposal are three-fold:
* As we've been working on the OpenAPI work for various services, we've found ourselves copy-pasting a lot of the code between these services. This has occasionally led to issues when those copies are incomplete [1][2]. Historically speaking, copy-pasting of code between services is a sure sign that this code should be generalised and placed in an oslo library * I have previously noted [3] that oslo.service contains some non- eventlet-related WSGI routing code, and there are questions around whether (a) that code should have been placed there in the first place and (b) how we can maintain that long-term once the eventlet code is removed (the 'oslo_service.wsgi' module has side effects since it imports the backend configuration stuff). * I have also raised some concerns around our use of paste.deploy and routes [1], both of which are minimally maintained nowadays. Many oslo libraries are designed to abstract their underlying libraries, allowing users to switch between e.g. different messaging backends (oslo.messaging) or caching services (oslo.cache).
Taken together, I think now would be a good time to provide a new library. I have an initial prototype available [4] which is effectively just a refactoring of the code from oslo.service, but I expect to add both more functionality to this existing code from existing consumers (Nova, Manila, Cinder etc.) and to add the openapi validation machinery. I imagine longer-term, this should evolve to allow us to replace the underlying libraries. However, we should obviously not get into the business of writing our own web framework. I also don't think it would make sense for all services to adopt all aspects of this project, since not all projects have any OpenAPI efforts ongoing at the moment and not all of them use the pastedeploy-routes-webob combo.
Given the above rationale and caveats, what do people think? Are there any objections to this idea? Please let me know. If there is not, I will go figure out how to get the ball rolling on this.
Cheers, Stephen
Hi Stephen,
Over the years, I found it very annoying that in OpenStack, there was no standard ways to write an API server, with all projects using a different framework. For example: - flask (keystone, cloudkitty, designate, octavia...) - paste (nova, neutron, swift...) - falcon (barbican, zaqar...)
I found it then hard to deal with, and it is also annoying to have to learn them all.
If oslo.wsgi can help having a unified framework, and if we don't fall into the unified standard trap: https://xkcd.com/927/
then it's a good thing! I'd love it if it became a TC goal to have all services switch to some kind of unified API framework.
This isn't the goal of the project. I touched on this with this statement:
I also don't think it would make sense for all services to adopt all aspects of this project, since not all projects have any OpenAPI efforts ongoing at the moment and not all of them use the pastedeploy-routes-webob combo.
The goal here is purely to gather common code currently duplicated across multiple projects into a single location, though ideally in a way hides as much of the internal library usage as possible (more on this below).
However, I see you requirements.txt having:
Paste>=2.0.2 # MIT PasteDeploy>=1.5.0 # MIT Routes>=2.3.1 # MIT WebOb>=1.7.1 # MIT
Why doing that? Why not choosing for example Flask or fast-api? Is this because you're trying to do that for Nova at first?
That requirements.txt file is only there because we didn't have an easy way to validate extras in the requirements-check job. I've now fixed this, so I expect to move much of this into separate extras.
I once wrote my own service myself, I found that flask was nice because I only needed to write a decorator for selecting the route. Example:
@app.route('/healthcheck', methods=['GET']) def health_check(): return jsonify({'status': 'ok', 'service': 'foo'}), 200
and also managed to do the same for the policy. Example:
@policy_checker('foo:add') def add_bar(): ....
Is this something that oslo.wsgi will provide without its users having to reinvent such wheel?
Not initially, no. Anything derived or based on Nova is wedded to the routes + paste.deploy + webob model for now and (at least initially) we are stuck with those. Use of a common oslo.wsgi Router class that hides its usage of Routes *would* allow us to swap out Routes in the future, however, I don't see us ever moving to a decorator approach for routing rather than the hardcoded mapping of URLs to controllers. Given my recent experience with the OpenAPI efforts there, such an effort would require a a huge amount of rework for projects like Nova and provide limited (and questionable) value.
Also, is there any doc on how to write a new service using oslo.wsgi? It'd be great to have a quick example like a foo/api.py so it'd be easy to start with it.
I don't know how much sense this would make. I would expect this project to be a holding place for code that is commonly shared across projects. At some point we might have people using it to bootstrap a new project, but it seems more likely that people would be using it to replace their existing in-tree version of e.g. a Router with a common one from oslo.wsgi. Hope this clarifies things, Stephen
Thanks a lot for this initiative, Cheers,
Thomas Goirand (zigo)