{"id":15019718,"url":"https://github.com/libcommon/flask-routes-py","last_synced_at":"2026-02-08T00:01:34.772Z","repository":{"id":62575402,"uuid":"268208706","full_name":"libcommon/flask-routes-py","owner":"libcommon","description":"Python library for Flask to define routes as classes, which can then be auto-registered with one or more apps.","archived":false,"fork":false,"pushed_at":"2022-12-26T21:32:07.000Z","size":63,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-28T10:11:13.202Z","etag":null,"topics":["flask","library","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/libcommon.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2020-05-31T04:28:20.000Z","updated_at":"2020-06-07T00:19:01.000Z","dependencies_parsed_at":"2023-01-31T01:45:48.784Z","dependency_job_id":null,"html_url":"https://github.com/libcommon/flask-routes-py","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":"libcommon/template-repo-py","purl":"pkg:github/libcommon/flask-routes-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libcommon%2Fflask-routes-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libcommon%2Fflask-routes-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libcommon%2Fflask-routes-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libcommon%2Fflask-routes-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libcommon","download_url":"https://codeload.github.com/libcommon/flask-routes-py/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libcommon%2Fflask-routes-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29213455,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T23:58:20.073Z","status":"ssl_error","status_checked_at":"2026-02-07T23:58:07.729Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["flask","library","python"],"created_at":"2024-09-24T19:53:56.127Z","updated_at":"2026-02-08T00:01:34.628Z","avatar_url":"https://github.com/libcommon.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flask-routes-py\n\n## Overview\n\nThe Flask web framework provides the decorator [@app.route](https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.route)\nto define handlers for routes, which is the recommended method for simple web apps. However, using this method requires\nthat route handlers be tied to a specific app, and can make it difficult to track/unit test routes for larger web apps.\n`flask-routes-py` provides mixins for defining routes as classes with static (`classmethod`) handlers, with optional extras\nlike integrated request parameter parsing with [flask-reqparser-py](https://github.com/libcommon/flask-reqparser-py), and\nautomated route discovery and registration with [lc-registry](https://github.com/libcommon/registry-py).\n\n## Installation\n\n### Install from PyPi (preferred method)\n\n```bash\npip install lc-flask-routes\npip install lc-flask-routes[reqparser]  # enable support for lc_flask_reqparser\npip install lc-flask-routes[registry]   # enable support for lc_registry\npip install lc-flask-routes[all]        # enable all options\n```\n\n### Install from GitHub with Pip\n\n```bash\npip install git+https://github.com/libcommon/flask-routes-py.git@vx.x.x#egg=lc_flask_routes\n```\n\nwhere `x.x.x` is the version you want to download.\n\n## Install by Manual Download\n\nTo download the source distribution and/or wheel files, navigate to\n`https://github.com/libcommon/flask-routes-py/tree/releases/vx.x.x/dist`, where `x.x.x` is the version you want to install,\nand download either via the UI or with a tool like wget. Then to install run:\n\n```bash\npip install \u003cdownloaded file\u003e\n```\n\nDo _not_ change the name of the file after downloading, as Pip requires a specific naming convention for installation files.\n\n## Dependencies\n\n`flask-routes-py` depends on, and is designed to work with, the \n[Flask framework](https://flask.palletsprojects.com/en/1.1.x/).  Optional dependencies also include\n[flask-reqparser-py](https://github.com/libcommon/flask-reqparser-py) for integrated request parameter parsing, and\n[lc-registry](https://github.com/libcommon/registry-py) for route auto-discovery. Only Python versions \u003e= 3.6 are\nofficially supported.\n\n## Getting Started\n\nDefine a base class that extends either the `BaseRouteMixin` or `BaseRouteWithParserMixin` class\n(if installed with `[reqparser]` or `[all]` options) that all other route classes will extend. This class could\ncontain any helper methods or class variables needed by all routes, but should _not_ define the `ROUTE_MAP` class\nvariable.\n\n```python\nfrom typing import Any, Dict, Optional\n\nimport flask\nfrom lc_flask_routes import (\n    BaseRouteMixin,\n    BaseRouteWithParserMixin,\n    RouteResponse,\n    WerkzeugLocalProxy\n)\nfrom lc_flask_reqparser import RequestParser\n\n\nclass BaseRoute(BaseRouteMixin):\n    \"\"\"Base route.\"\"\"\n    __slots__ = ()\n\n\nclass BaseParserRoute(BaseRouteWithParserMixin):\n    \"\"\"Base route with request parser.\"\"\"\n    __slots__ = ()\n\n    @classmethod\n    def gen_request_parser(cls) -\u003e Optional[RequestParser]:\n        return (RequestParser()\n                .add_argument(\"base_argument_for_all_routes\"))\n\n\nclass IndexRoute(BaseRoute):\n    \"\"\"Route: /\n    Endpoint: \"index\"\n    Description: Splash page\n    \"\"\"\n    __slots__ = ()\n\n    ROUTE_MAP = {\"/\": {\"endpoint\": \"index\", \"methods\": [\"GET\", \"POST\"]}}\n\n    @classmethod\n    def get(cls,\n            app: WerkzeugLocalProxy,\n            request: WerkzeugLocalProxy,\n            session: WerkzeugLocalProxy,\n            route_kwargs: Dict[str, Any]) -\u003e RouteResponse:\n        return \"\u003ch1\u003eSplash Page\u003c/h1\u003e\"\n\n    @classmethod\n    def post(cls,\n             app: WerkzeugLocalProxy,\n             request: WerkzeugLocalProxy,\n             session: WerkzeugLocalProxy,\n             route_kwargs: Dict[str, Any]) -\u003e RouteResponse:\n        return flask.redirect(url_for(\"index\"))\n\n\nif __name__ == \"__main__\":\n    app = flask.Flask(__name__)\n    IndexRoute.register_route(app)\n    app.run()\n```\n\nThe `ROUTE_MAP` class variable should only be defined on non-base routes, and its structure mimics the parameters\nfor Flask's `@app.route` decorator, which really calls [add_url_rule](https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.add_url_rule)\nunder the hood. Each key is a URI, and each corresponding value are the keyword arguments passed to `add_url_rule`. See Flask's documentation\nfor expectations and limitations of that function. `BaseRouteMixin` has a `register_route` method that accomplishes the same result as `@app.route`.\nEach route class must be registered individually (unless using `RouteRegistryMixin` - see below).\n\nIf installed with the `[registry]` or `[all]` options, `flask-routes-py` also exposes a `RouteRegistryMixin` class to be used for auto-discovery\nof route classes using metaprogramming. Define a Python `metaclass` that extends `RouteRegistryMixin`, then define a base class that uses this\n`metaclass`.\n\n```python\nfrom abc import ABCMeta\nfrom typing import Any, Dict\n\nimport flask\nfrom lc_flask_routes import (\n    BaseRouteMixin,\n    BaseRouteWithParserMixin,\n    RouteResponse,\n    WerkzeugLocalProxy\n)\n\n\nclass RouteRegistry(RouteRegistryMixin, ABCMeta):\n    \"\"\"Route registry.\"\"\"\n    __slots__ = ()\n\n    _REGISTRY = dict()\n\n\nclass BaseRoute(BaseRouteMixin, metaclass=RouteRegistry):\n    \"\"\"Base route. Any child class will be registered in\n    RouteRegistry's _REGISTRY class variable automatically\n    (as long as it's in scope).\"\"\"\n\n\nclass IndexRoute(BaseRoute):\n    \"\"\"Route: /\n    Endpoint: \"index\"\n    Description: Splash page\n    \"\"\"\n    __slots__ = ()\n\n    ROUTE_MAP = {\"/\": {\"endpoint\": \"index\", \"methods\": [\"GET\"]}}\n\n    @classmethod\n    def get(cls,\n            app: WerkzeugLocalProxy,\n            request: WerkzeugLocalProxy,\n            session: WerkzeugLocalProxy,\n            route_kwargs: Dict[str, Any]) -\u003e RouteResponse:\n        return \"\u003ch1\u003eSplash Page\u003c/h1\u003e\"\n\n\nclass LoginRoute(BaseRoute):\n    \"\"\"Route: /login\n    Endpoint: \"login\"\n    Description: Login workflow\n    \"\"\"\n    __slots__ = ()\n\n    ROUTE_MAP = {\"/login\": {\"endpoint\": \"login\", \"methods\": [\"POST\"]}}\n\n    @classmethod\n    def post(cls,\n             app: WerkzeugLocalProxy,\n             request: WerkzeugLocalProxy,\n             session: WerkzeugLocalProxy,\n             route_kwargs: Dict[str, Any]) -\u003e RouteResponse:\n        // Do some work to verify identity\n        return flask.redirect(url_for(\"index\"))\n\n\nif __name__ == \"__main__\":\n    app = flask.Flask(__name__)\n    # Register IndexRoute and LoginRoute with app\n    RouteRegistry.register_routes(app)\n    app.run()\n```\n\n`RouteRegistryMixin` exposes two methods for registering routes with an app: `register_routes` and `register_routes_where`.\nAs shown above, `register_routes` will register all routes in the registry without any filtering, whereas `register_routes_where`\nevaluates a provided predicate on reach route class before registering it. This could be useful, for example, if the same registry is being used\nto initialize two different apps based on a class variable.\n\n## Contributing/Suggestions\n\nContributions and suggestions are welcome! To make a feature request, report a bug, or otherwise comment on existing\nfunctionality, please file an issue. For contributions please submit a PR, but make sure to lint, type-check, and test\nyour code before doing so. Thanks in advance!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibcommon%2Fflask-routes-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibcommon%2Fflask-routes-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibcommon%2Fflask-routes-py/lists"}