Framework
cherrypy/cherrypy avatar
cherrypy/cherrypy

cherrypy/cherrypy: the object model of Python presented as a website

CherryPy is a pythonic, object-oriented HTTP framework. https://cherrypy.dev

1,946 stars369 forksPythonBSD-3-Clause

At a glance

What is it?
CherryPy is a BSD licensed, pure Python HTTP framework where an exposed method on an object becomes a URL, and the framework ships with its own WSGI server through cheroot. It is a decade old and classified as production stable, its versions come from setuptools-scm rather than release tags, and it asks you to bring your own templates.
Who is it for?
Adopt CherryPy when you want a small, dependency light framework that maps a Python object graph directly onto URLs and you prefer a WSGI stack you can host behind any WSGI server, since the framework itself is stable, BSD licensed and pure Python.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An exposed method is a URL

CherryPy is described as a pythonic, object-oriented HTTP framework, and the entire idea fits in a dozen lines. A method decorated with `@cherrypy.expose` becomes reachable over HTTP, and the object holding it is the application:

python
import cherrypy

class HelloWorld(object):
    @cherrypy.expose
    def index(self):
        return "Hello World!"

cherrypy.quickstart(HelloWorld())

The design claim in the documentation is that this lets you build a web application much as you would build any other object-oriented program, with the result being more concise and readable code written faster, because it is all just properties and methods. The `index` method becomes the root of the object's URL space, and sibling methods become sibling paths, using the Python object model rather than a routing table as the source of truth.

That model scales up, according to the project: the same intuition keeps working as systems grow, with the Python object model dynamically presented as a website or an API. It is the one design decision that makes CherryPy feel different from the URL dispatch tables that dominate Python web development, and it is also the one that costs you when you need a route that does not map onto a method, such as a path that has to exist on several objects at once.

One expectation to set early: understanding the documentation assumes you already have a general understanding of Python and web development. The project puts tutorials inside the repository, at `cherrypy/tutorial`, plus a wiki and a support page, but it does not try to teach web development from scratch.

A decade old, production stable, and versioned by git

The project makes an unusual claim for something that looks dated: it is more than ten years old and has proven fast and very stable, and the package classifiers list the development status as Production/Stable. The claim that it is used in production by many sites, from the simplest to the most demanding, is the maintainers' own, and it is the kind of statement worth testing against your own requirements rather than taking on trust.

The repository carries the evidence of long maintenance. There is a `CHANGES.rst` change log, a `man/` directory for manual pages, `requirements/` and `dependencies/` directories that separate declared from pinned dependencies, `bindep.txt` for system level packages, a `tox.ini` and a `toxfile.py` for environment matrices, `pytest.ini` and a `conftest.py` for the test suite, and a `visuals/` directory of documentation assets. The linting configuration is layered too, with `.ruff.toml`, `.flake8` and `.yamllint` alongside a `.pre-commit-config.yaml`.

One detail catches the eye for anyone automating releases. The repository has no GitHub releases at all, and the version in `pyproject.toml` is marked dynamic and derived through `setuptools-scm`, which takes it from the repository's own version control metadata. The practical effect is that the version is whatever the checkout says it is, so pinning is done against the release on PyPI rather than against a tag you can see in the repository, and the last push on 2026-10-12 is the better signal of current activity than a release list would have been.

cheroot serves, portend waits for a free port

CherryPy is pure Python, and the project lists pure-python among its topics, but it does not implement an HTTP server from scratch. The dependency list in `pyproject.toml` shows the split clearly:

toml
dependencies = [
  "cheroot >= 8.2.1",
  "portend >= 2.1.1",
  "more_itertools",
  "filelock",
  "jaraco.collections",
]

`cheroot` is the WSGI server, and it is the piece you would look at first if you care about server behaviour, since the version floor of 8.2.1 is what the framework asks for. `portend` is the next runtime dependency, with a version floor of 2.1.1. `more_itertools` and `jaraco.collections` are small general purpose helpers, and `filelock` is there because a server process that runs in several workers needs to coordinate on disk.

There is one conditional dependency that shows the project's history. `pywin32` is required only on Windows, only on CPython, and only below Python 3.10:

toml
'pywin32 >= 227; sys_platform == "win32" and implementation_name == "cpython" and python_version < "3.10"',

The comment in the file says pywin32 is disabled while a build is unavailable, with a reference to an issue. This is the kind of detail that only shows up in a framework that has been carried across a decade of platform changes, and it also tells you that on a current Python 3.10 or newer Windows install, the dependency list is short.

Python 3.9 to 3.13, and a WSGI world rather than an ASGI one

The supported range is declared twice. `requires-python` is set to 3.9 or newer, and the classifiers list Python 3.9, 3.10, 3.11, 3.12 and 3.13, with implementations CPython, Jython and PyPy named. The README badges make the same point with a slightly different framing, one for Python 3 only with a pip requirement of 18.0.0 or newer, and one for Python 3 and 2 with a pip requirement below 18.0.0, which is the older packaging convention rather than a claim of Python 2 support.

The more consequential boundary is the topic list and the classifiers, which place CherryPy in the WSGI world: the classifiers name WSGI, WSGI Application and WSGI Server alongside the general HTTP categories, and the documentation is built with Read the Docs.

That has a direct effect on how the framework fits into a modern deployment. A WSGI application is served by a WSGI server, so CherryPy is at home behind a conventional synchronous stack, and `quickstart` is the shortcut for development. It is not an ASGI framework, and nothing in this repository's metadata suggests an async request model, so if your services are already built around async Python and an ASGI server, CherryPy is not a natural fit even though the language matches.

The second half of that sentence is the honest comparison. The alternative is an ASGI framework, and the difference in approach is not about code quality but about the concurrency model: a synchronous WSGI application handles one request per worker at a time, while an async framework can interleave many on a single event loop. Choosing CherryPy means choosing the simpler, synchronous model and taking the deployment that goes with it.

Where CherryPy is the wrong choice

Three situations stand out, and none of them is about the framework's quality.

The first is a greenfield async service. The framework's model is synchronous request handling with a WSGI server underneath, so a project whose architecture is built around async Python will spend its time fighting the stack rather than using it.

The second is a team expecting a full stack. What this repository provides is the HTTP framework layer, the object to URL mapping and the server. It does not include a template engine, an object relational mapper, form handling or an administration interface, and the dependency list has nothing that would suggest otherwise. Assembling those yourself is entirely reasonable, but it is work the project does not do for you, and a framework that includes them would give you a shorter path to a first screen.

The third is a project with a route shape that does not map onto objects. Because the URL space is the object tree, a URL that must be served by several different resources, or one that needs a pattern the method name cannot express, is awkward. CherryPy does have tools for dispatching, and the documentation covers them, but the natural case for the framework is the case where a URL is a method on a class.

None of these make the framework bad. They make it a specific choice, and the project's own documentation is unusually direct about its audience, listing an audience of developers and an operating system of OS Independent.

Community and support channels

An old framework can have an old community, so it is worth knowing what support exists. The documentation site at docs.cherrypy.dev carries the reference material and a support page that lists several avenues, and the repository points to a Stack Overflow tag, a Google group mailing list and a Gitter room. There is a wiki with a page called the Zen of CherryPy, which the contributing guidance tells you to absorb, and a contribution guide on the documentation site.

The commercial angle is the Tidelift subscription, which the README explains in its own terms: the maintainers of CherryPy and of thousands of other packages work with Tidelift to deliver one enterprise subscription covering the open source a company uses. That is an arrangement where a company pays for the maintenance of a dependency it does not own, and it is worth a look if you depend on CherryPy in a product and want a support relationship that does not depend on a single volunteer.

For most adopters, though, the practical question is narrower: whether a framework with a decade of history, a stable changelog and a working test matrix is the right level of risk for what you are building. The repository's own evidence, a Production/Stable classifier, a `CHANGES.rst`, tox environments and continuous linting, is a reasonable answer to that, and the last push on 2026-10-12 says the project is not in maintenance-only mode.

Editorial conclusion

Adopt CherryPy when you want a small, dependency light framework that maps a Python object graph directly onto URLs and you prefer a WSGI stack you can host behind any WSGI server, since the framework itself is stable, BSD licensed and pure Python. Do not adopt it for a new async project, because the framework sits in the WSGI world rather than the ASGI one, and do not adopt it expecting a batteries included stack, since templates, forms, an ORM and an admin interface are not part of what this repository provides. Verify first that the cheroot version pulled in satisfies your server requirements, that your Python version falls inside the supported range of 3.9 through 3.13, and that the absence of GitHub releases does not upset your pinning, since the version is derived from setuptools-scm.

Frequently asked questions

How do I write a Hello World application with CherryPy?

Expose a method with `@cherrypy.expose` on a class, return a string from it, and start the framework with `cherrypy.quickstart(HelloWorld())`. The `index` method serves the root of that object's URL space.

Which Python versions does CherryPy support?

The project metadata sets `requires-python` to 3.9 or newer and lists classifiers for Python 3.9 through 3.13, with CPython, Jython and PyPy named as implementations. The README badges point to a pip requirement of 18.0.0 or newer for Python 3 only.

What HTTP server does CherryPy use?

The dependency list in `pyproject.toml` requires `cheroot >= 8.2.1` for the WSGI server and `portend >= 2.1.1` for port handling, alongside `more_itertools`, `filelock` and `jaraco.collections`. CherryPy itself is pure Python.

How is the CherryPy version determined if the repository has no releases?

The version is dynamic in `pyproject.toml` and comes from `setuptools-scm`, which derives it from the repository's version control metadata. The build system requires setuptools 61.2 or newer and setuptools-scm 7.0.0 or newer, so a checkout reports its own version.

Does CherryPy include a template engine, ORM or admin interface?

The repository and its dependency list cover the HTTP framework, the object to URL mapping and the server, and the project describes itself as an HTTP framework for developers rather than a full stack. No templating or persistence library appears in the declared dependencies, so those are choices you make yourself.

Official sources

  1. cherrypy/cherrypy on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cherrypy-cherrypy.svg)](https://hysenlabs.com/projects/cherrypy-cherrypy)

Was this useful?