{"id":18759171,"url":"https://github.com/gaufung/tindo","last_synced_at":"2025-12-02T12:30:15.128Z","repository":{"id":93268833,"uuid":"103276206","full_name":"gaufung/tindo","owner":"gaufung","description":"Tindo: A Simple WSGI Compatible Web Framwork","archived":false,"fork":false,"pushed_at":"2018-03-31T06:38:08.000Z","size":59,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-29T03:47:38.819Z","etag":null,"topics":["framework","web","wsgi"],"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/gaufung.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-12T13:45:37.000Z","updated_at":"2018-03-31T06:38:09.000Z","dependencies_parsed_at":"2023-03-16T02:01:02.138Z","dependency_job_id":null,"html_url":"https://github.com/gaufung/tindo","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/gaufung%2Ftindo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaufung%2Ftindo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaufung%2Ftindo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaufung%2Ftindo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gaufung","download_url":"https://codeload.github.com/gaufung/tindo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239650877,"owners_count":19674831,"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":["framework","web","wsgi"],"created_at":"2024-11-07T17:49:22.960Z","updated_at":"2025-12-02T12:30:15.080Z","avatar_url":"https://github.com/gaufung.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"**tindo:**\n\nA micro-framework based on wsgiref\n\n# 0 *install*\n```shell\npip install tindo\n```\n\n# 1 **Main Components**\n\n+ ~~*get* decorator: for HTTP GET Method~~\n+ ~~*post* decorator: for HTTP POST Method~~\n+ *route* decorator: for HTTP GET and POST methods\n+ *Route* class: wrap the decorated functions, which contains the `match(self, url)` methods to determinate whether\nthe url match the route nor not.\n+ *Request* class: wrap the wsgi's `environ` dictionary into more useful apis, including `methods`, `cookies`, `path`\n and `inputs` etc.\n+ *Response* class: a high-level of wsgi's `status` and `response_headers`.\n+ *view* decorator: a specific html template to render\n+ *Tindo* class: main class of web framework. To approach the multi-thread environment, use threading module'\ns `Local` class.\n\n# 2 **Usages**\n\nThe example folder contains the minimum demo using `tindo`.\n\n```\n- example\n    - static \n       - style.css\n    - templates\n       - index.html\n       - name.html\n       - register.html\n       - comment.html\n       - register.html\n       - registered.html\n       - session.html\n    - app.py\n    - urls.py\n```\n\n## 2.1 urls.py\nThis module defines the main `routes` rules of web application, \njust like `Django`.\n\n\n### 2.1.1 GET Method\n\n```python\n\n@view('index.html')\n@route('/')\ndef index():\n    return dict()\n\n```\nUsing `get` decorator to decorate a function. Using `view`\ndecorator to decide which template to be rendered.\nIf no variables in the template, just return a `dict`.\n\n### 2.1.2 POST Method\n\n```python\n@view('register.html')\n@route('/register', methods=['GET', 'POST'])\ndef register():\n    i = ctx.request.input(firstname=None, lastname=None)\n    firstname = i.get('firstname')\n    lastname = i.get('lastname')\n    if firstname is None and lastname is None:\n        return dict(register=True)\n    else:\n        return dict(firstname=firstname, lastname=lastname)\n```\nThe thread-safe `ctx` variable includes current request, which\ncontains `posted` values in `wsgi.input` dictionary.\n\n\n### 2.1.3 GET Query\n\n```python\n@view('name.html')\n@route('/user/\u003cusername\u003e')\ndef user(name):\n    return dict(name=name)\n    \n@view('comment.html')\n@route('/user/\u003cname\u003e/\u003cgroup\u003e')\ndef comment(name, group):\n    return dict(name=name, group=group)\n```\n\nReferring `flask` route, url can contain a query variable. If \n`get` decorator with `\u003cvariable\u003e`, the route will convert the \nurl's last component as parameter and invoke the function.\n\n### 2.1.4 Session\nSession is used to keep identification of individual client. \n[This article](http://eli.thegreenplace.net/2011/06/24/django-sessions-part-i-cookies/)\npoints out how session works. In `tindo`, the application contain a global \ndictionary that keeps every session-id. Each session is a dictionary instance in memory.\n\n```python\n@view('session.html')\n@route('/session')\ndef session():\n    sess = ctx.response.session\n    return dict(name=sess.name)\n``` \n\n## 2.2 app.py\n\nThis module is main part of web application. Just import `tindo` and\nmake Tindo instance and run it. But it needs to import `url` module.\n```python\nimport os\nfrom tindo import Tindo\nimport urls\napp = Tindo(os.path.dirname(os.path.abspath(__file__)))\napp.add_module(urls)\nif __name__ == '__main__':\n    app.run()\n```\n\n# 3 RoadMaps\n\n- [ ] Export it to Python 3.x\n- [x] Add session feature\n- [x] Refactor\n\n# 4 Update Notes\n\n+ update `route` decorator and deprecate `get` and `post` decorators. 17. Sep. 2017\n+ re-organize `tindo.py` wsgi protocol using `__call__`. 18. Sep. 2017\n+ add `local` module which behave like `threading.local`. 19. Sep. 2017\n+ add `manage.py` script to control `test` and `app`, refactor the ugly `reload(sys)`\nstatement, and use absolute import features. 20. Sep. 2017\n+ add Tindo's `__init__.py` to make less `import` statement.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaufung%2Ftindo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgaufung%2Ftindo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaufung%2Ftindo/lists"}