# htagweb
[![Test](https://github.com/manatlan/htagweb/actions/workflows/on_commit_do_all_unittests.yml/badge.svg)](https://github.com/manatlan/htagweb/actions/workflows/on_commit_do_all_unittests.yml)
<a href="https://pypi.org/project/htagweb/">
<img src="https://badge.fury.io/py/htagweb.svg?x" alt="Package version">
</a>
This module exposes htag's runners for the web. It's the official runners to expose
htag apps on the web, to handle multiple clients/session in the right way.
## Runner
It's the real runner to expose htag apps in a real production environment, and provide
all features, while maintaining tag instances like classical/desktop htag runners.
All htag apps are runned in its own process, and an user can only have an instance of an htag app. (so process are recreated when query params changes)
Process live as long as the server live
**Features**
* based on [starlette](https://pypi.org/project/starlette/)
* use session
* compatible with **uvloop** !!!
* compatible with multiple gunicorn/uvicorn/webworkers !!!
* compatible with [tag.update()](https://manatlan.github.io/htag/tag_update/)
* works on gnu/linux, ios ~~or windows~~ (from py3.8 to py3.11)! (**not py3.7 anymore ;-(**)
* real starlette session available (in tag.state, and starlette request.session)
* compatible with oauth2 authent ( [authlib](https://pypi.org/project/Authlib/) )
* 'parano mode' (can aes encrypt all communications between client & server ... to avoid mitm'proxies on ws/http interactions)
* auto reconnect websocket
### Instanciate
Like a classical starlette'app :
```python
from htagweb import Runner
from yourcode import YourApp # <-- your htag class
app=Runner( YourApp, ... )
if __name__=="__main__":
app.run()
```
You can use the following parameters :
#### host (str)
The host to bind to. (default is "0.0.0.0")
#### port (int)
The port to bind to. (default is 8000)
#### debug (bool)
- When False: (default) no debugging facilities
- When True: use starlette debugger.
#### parano (bool)
- When False: (default) interactions between front/ui and back are in clear text (json), readable by a MITM.
- When True: interactions will be encrypted (less readable by a MITM, TODO: will try to use public/private keys in future)
this parameter is available on `app.handle(request, obj, ... parano=True|False ...)` too, to override defaults !
#### http_only (bool)
- When False: (default) it will use websocket interactions (between front/ui and back), with auto-reconnect feature.
- When True: it will use http interactions (between front/ui and back). But "tag.update" feature will not be available.
this parameter is available on `app.handle(request, obj, ... http_only=True|False ...)` too, to override defaults !
#### timeout_interaction (int)
It's the time (in seconds) for an interaction (or an initialization) for answering. If the timeout happens : the process/instance is killed.
By default, it's `60` seconds (1 minute).
#### timeout_inactivity (int)
It's the time (in seconds) of inactivities, after that : the process is detroyed.
By default, it's `0` (process lives as long as the server lives).
IMPORTANT : the "tag.update" feature doesn't reset the inactivity timeout !
### to add an endpoint (add_route)
Example to add a static endpoint :
```python
from starlette.responses import PlainTextResponse
async def serve(req):
return PlainTextResponse("body {}")
app=Runner( App, debug=False )
app.add_route("/my.css", serve)
```
Example to add another htag app on another endpoint :
```python
async def serve(req):
return await req.app.handle(req, App2 )
app=Runner( App, debug=False )
app.add_route("/my_other_app", serve)
```
-------------------------------
## Roadmap / futur
- more unittests !!!!!!!!!!!!!!!!
- better logging !!!!!!!!!!!!!!!!
- parano mode : use public/private keys ?
## Examples
A "hello world" could be :
```python
from htag import Tag
class App(Tag.div):
def init(self):
self<= "hello world"
from htagweb import Runner
Runner( App ).run()
```
or, with gunicorn (in a `server.py` file, as following):
```python
from htag import Tag
class App(Tag.div):
def init(self):
self<= "hello world"
from htagweb import Runner
app=Runner( App )
```
and run server :
```bash
gunicorn -w 4 -k uvicorn.workers.UvicornH11Worker -b localhost:8000 --preload server:app
```
See a more advanced example in [examples folder](https://github.com/manatlan/htagweb/tree/master/examples)
```bash
python3 examples/main.py
```
Raw data
{
"_id": null,
"home_page": "https://github.com/manatlan/htagweb",
"name": "htagweb",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "htag, webserver",
"author": "manatlan",
"author_email": "manatlan@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/d2/a8/8c616da8b20fd407e8bf0b3faa450c441886d9386d536d771583ce2883b7/htagweb-0.42.3.tar.gz",
"platform": null,
"description": "# htagweb \n[![Test](https://github.com/manatlan/htagweb/actions/workflows/on_commit_do_all_unittests.yml/badge.svg)](https://github.com/manatlan/htagweb/actions/workflows/on_commit_do_all_unittests.yml)\n\n<a href=\"https://pypi.org/project/htagweb/\">\n <img src=\"https://badge.fury.io/py/htagweb.svg?x\" alt=\"Package version\">\n</a>\n\nThis module exposes htag's runners for the web. It's the official runners to expose\nhtag apps on the web, to handle multiple clients/session in the right way.\n\n## Runner\n\nIt's the real runner to expose htag apps in a real production environment, and provide\nall features, while maintaining tag instances like classical/desktop htag runners.\n\nAll htag apps are runned in its own process, and an user can only have an instance of an htag app. (so process are recreated when query params changes)\nProcess live as long as the server live\n\n**Features**\n\n * based on [starlette](https://pypi.org/project/starlette/)\n * use session\n * compatible with **uvloop** !!!\n * compatible with multiple gunicorn/uvicorn/webworkers !!!\n * compatible with [tag.update()](https://manatlan.github.io/htag/tag_update/)\n * works on gnu/linux, ios ~~or windows~~ (from py3.8 to py3.11)! (**not py3.7 anymore ;-(**)\n * real starlette session available (in tag.state, and starlette request.session)\n * compatible with oauth2 authent ( [authlib](https://pypi.org/project/Authlib/) )\n * 'parano mode' (can aes encrypt all communications between client & server ... to avoid mitm'proxies on ws/http interactions)\n * auto reconnect websocket\n\n### Instanciate\n\nLike a classical starlette'app :\n\n```python\nfrom htagweb import Runner\nfrom yourcode import YourApp # <-- your htag class\n\napp=Runner( YourApp, ... )\nif __name__==\"__main__\":\n app.run()\n```\n\nYou can use the following parameters :\n\n#### host (str)\n\nThe host to bind to. (default is \"0.0.0.0\")\n\n#### port (int)\n\nThe port to bind to. (default is 8000)\n\n#### debug (bool)\n\n- When False: (default) no debugging facilities\n- When True: use starlette debugger.\n\n\n#### parano (bool)\n\n- When False: (default) interactions between front/ui and back are in clear text (json), readable by a MITM.\n- When True: interactions will be encrypted (less readable by a MITM, TODO: will try to use public/private keys in future)\n\nthis parameter is available on `app.handle(request, obj, ... parano=True|False ...)` too, to override defaults !\n\n#### http_only (bool)\n\n- When False: (default) it will use websocket interactions (between front/ui and back), with auto-reconnect feature.\n- When True: it will use http interactions (between front/ui and back). But \"tag.update\" feature will not be available.\n\nthis parameter is available on `app.handle(request, obj, ... http_only=True|False ...)` too, to override defaults !\n\n#### timeout_interaction (int)\n\nIt's the time (in seconds) for an interaction (or an initialization) for answering. If the timeout happens : the process/instance is killed.\nBy default, it's `60` seconds (1 minute).\n\n#### timeout_inactivity (int)\n\nIt's the time (in seconds) of inactivities, after that : the process is detroyed.\nBy default, it's `0` (process lives as long as the server lives).\n\nIMPORTANT : the \"tag.update\" feature doesn't reset the inactivity timeout !\n\n\n### to add an endpoint (add_route)\n\nExample to add a static endpoint :\n\n```python\nfrom starlette.responses import PlainTextResponse\n\nasync def serve(req):\n return PlainTextResponse(\"body {}\")\n\napp=Runner( App, debug=False )\napp.add_route(\"/my.css\", serve)\n```\n\nExample to add another htag app on another endpoint :\n\n```python\nasync def serve(req):\n return await req.app.handle(req, App2 )\n\napp=Runner( App, debug=False )\napp.add_route(\"/my_other_app\", serve)\n```\n\n\n-------------------------------\n\n## Roadmap / futur\n\n - more unittests !!!!!!!!!!!!!!!!\n - better logging !!!!!!!!!!!!!!!!\n - parano mode : use public/private keys ?\n\n\n## Examples\n\nA \"hello world\" could be :\n\n```python\nfrom htag import Tag\n\nclass App(Tag.div):\n def init(self):\n self<= \"hello world\"\n\nfrom htagweb import Runner\nRunner( App ).run()\n```\n\nor, with gunicorn (in a `server.py` file, as following):\n\n```python\nfrom htag import Tag\n\nclass App(Tag.div):\n def init(self):\n self<= \"hello world\"\n\nfrom htagweb import Runner\napp=Runner( App )\n```\n\nand run server :\n\n```bash\ngunicorn -w 4 -k uvicorn.workers.UvicornH11Worker -b localhost:8000 --preload server:app\n```\n\nSee a more advanced example in [examples folder](https://github.com/manatlan/htagweb/tree/master/examples)\n\n```bash\npython3 examples/main.py\n```\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "It's a robust webserver (http/ws) for hosting htag apps on the web (a process by user)",
"version": "0.42.3",
"project_urls": {
"Documentation": "https://github.com/manatlan/htagweb",
"Homepage": "https://github.com/manatlan/htagweb",
"Repository": "https://github.com/manatlan/htagweb"
},
"split_keywords": [
"htag",
" webserver"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1c021cd27b37a3826955075482f9edcb229c62283e08ac6ae4611dd9700c7a0f",
"md5": "2bff1d6b482200570612d090c1d6a157",
"sha256": "6207252eb50bf8692a492f6cd45ea7e5f00546b9cfefdf3623d9b6b9ab979429"
},
"downloads": -1,
"filename": "htagweb-0.42.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2bff1d6b482200570612d090c1d6a157",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 17367,
"upload_time": "2024-11-07T12:21:04",
"upload_time_iso_8601": "2024-11-07T12:21:04.083477Z",
"url": "https://files.pythonhosted.org/packages/1c/02/1cd27b37a3826955075482f9edcb229c62283e08ac6ae4611dd9700c7a0f/htagweb-0.42.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d2a88c616da8b20fd407e8bf0b3faa450c441886d9386d536d771583ce2883b7",
"md5": "306626b44a6349570b8251aa26e1783d",
"sha256": "925a4fd3576301fdcc83549a1bedb512a263155e175318d125f2fd21b0936a9c"
},
"downloads": -1,
"filename": "htagweb-0.42.3.tar.gz",
"has_sig": false,
"md5_digest": "306626b44a6349570b8251aa26e1783d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 15077,
"upload_time": "2024-11-07T12:21:05",
"upload_time_iso_8601": "2024-11-07T12:21:05.126021Z",
"url": "https://files.pythonhosted.org/packages/d2/a8/8c616da8b20fd407e8bf0b3faa450c441886d9386d536d771583ce2883b7/htagweb-0.42.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-07 12:21:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "manatlan",
"github_project": "htagweb",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "htagweb"
}