{"id":15662150,"url":"https://github.com/avanov/rhetoric","last_synced_at":"2026-03-06T05:44:15.178Z","repository":{"id":57461896,"uuid":"12616648","full_name":"avanov/Rhetoric","owner":"avanov","description":"Pyramid-like routes in Django","archived":false,"fork":false,"pushed_at":"2018-03-05T19:05:52.000Z","size":648,"stargazers_count":19,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-04-19T12:14:08.651Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://rhetoric.readthedocs.org/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avanov.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-05T12:00:18.000Z","updated_at":"2021-11-05T23:35:37.000Z","dependencies_parsed_at":"2022-08-28T01:51:59.971Z","dependency_job_id":null,"html_url":"https://github.com/avanov/Rhetoric","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanov%2FRhetoric","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanov%2FRhetoric/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanov%2FRhetoric/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avanov%2FRhetoric/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avanov","download_url":"https://codeload.github.com/avanov/Rhetoric/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252596395,"owners_count":21773844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T13:30:24.824Z","updated_at":"2026-03-06T05:44:15.119Z","avatar_url":"https://github.com/avanov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Rhetoric\n=============\n\n.. image:: https://pypip.in/v/Rhetoric/badge.png\n        :target: https://crate.io/packages/Rhetoric\n\n.. image:: https://pypip.in/d/Rhetoric/badge.png\n        :target: https://crate.io/packages/Rhetoric\n\n.. image:: https://api.travis-ci.org/avanov/Rhetoric.png\n        :target: https://travis-ci.org/avanov/Rhetoric\n\n.. image:: https://coveralls.io/repos/avanov/Rhetoric/badge.png?branch=develop\n        :target: https://coveralls.io/r/avanov/Rhetoric?branch=develop\n\nStatus: **Beta, Unstable API**.\n\nNaive implementation of Pyramid-like routes for Django projects.\n\n\nWhy it is worth your while\n--------------------------\n\nThere's a great article on why Pyramid routing subsystem is so convenient for\nweb developers -\n`Pyramid view configuration: Let me count the ways \u003chttp://blog.delaguardia.com.mx/pyramid-view-configuration-let-me-count-the-ways.html\u003e`_.\n\nAs a person who uses Pyramid as a foundation for his pet-projects, and Django - at work,\nI (the author) had a good opportunity to compare two different approaches to routing configuration\nprovided by these frameworks. And I totally agree with the key points of the article - Pyramid routes\nare more flexible and convenient for developers writing RESTful services.\n\nThe lack of flexibility of standard Django url dispatcher motivated me to\ncreate this project. I hope it will be useful for you,\nand if you liked the idea behind Rhetoric URL Dispatcher, please consider\n`Pyramid Web Framework \u003chttp://www.pylonsproject.org/\u003e`_ for one of your future projects.\n\n\nProject premises\n----------------\n\n* Rhetoric components try to follow corresponding Pyramid components whenever possible.\n* Integration with django applications shall be transparent to existing code whenever possible.\n* Performance of Rhetoric URL Dispatcher is worse than of the one of Pyramid, due to\n  naivety of the implementation and limitations imposed by the compatibility with Django API.\n\nInstallation\n-------------\n\nRhetoric is available as a PyPI package:\n\n.. code-block:: bash\n\n    $ pip install Rhetoric\n\nThe package shall be compatible with Python2.7, and Python3.3 or higher.\n\nIntegration with Django\n-----------------------\n\n#. Replace ``django.middleware.csrf.CsrfViewMiddleware`` with\n   ``rhetoric.middleware.CsrfProtectedViewDispatchMiddleware`` in your project's ``MIDDLEWARE_CLASSES``:\n\n   .. code-block:: python\n\n        # somewhere in a project_name.settings module\n\n        MIDDLEWARE_CLASSES = [\n            # ...\n            'rhetoric.middleware.CsrfProtectedViewDispatchMiddleware',\n            #'django.middleware.csrf.CsrfViewMiddleware',\n            # ...\n        ]\n\n#. Inside the project's `root urlconf \u003chttps://docs.djangoproject.com/en/dev/ref/settings/#std:setting-ROOT_URLCONF\u003e`_\n   (usually ``project_name.urls``):\n\n   .. code-block:: python\n\n       from django.conf.urls import patterns, include, url\n       # ... other imports ...\n       from rhetoric import Configurator\n\n       # ... various definitions ...\n\n       urlpatterns = patterns('',\n           # ... a number of standard django url definitions ...\n       )\n\n       # Rhetorical routing\n       # ------------------\n       config = Configurator()\n       config.add_route('test.new.routes', '/test/new/routes/{param:[a-z]+}')\n       config.scan(ignore=[\n           # do not scan test modules included into the project tree\n           re.compile('^.*[.]?tests[.]?.*$').match,\n           # do not scan settings modules\n           re.compile('^project_name.settings[_]?[_a-z09]*$').match,\n       ])\n       urlpatterns.extend(config.django_urls())\n\n#. Register views:\n\n   .. code-block:: python\n\n       # project_name.some_app.some_module\n\n       from rhetoric import view_config\n\n\n       @view_config(route_name=\"test.new.routes\", renderer='json')\n       def view_get(request, param):\n           return {\n               'Hello': param\n           }\n\n       @view_config(route_name=\"test.new.routes\", renderer='json', request_method='POST')\n       def view_post(request, param):\n           return {\n               'Hello': 'POST'\n           }\n\n#. From this point you can request ``/test/new/routes/\u003cparam\u003e`` with different methods.\n\nDocumentation\n-------------\n\nSee complete documentation at http://rhetoric.readthedocs.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanov%2Frhetoric","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favanov%2Frhetoric","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanov%2Frhetoric/lists"}