smdb-web-server


Namesmdb-web-server JSON
Version 0.3.3 PyPI version JSON
download
home_pagehttps://github.com/NightKey/smdb-server
SummaryA really basic, not so safe web server.
upload_time2024-05-16 14:31:06
maintainerNone
docs_urlNone
authorJanthó Dávid
requires_python>=3.7
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # SMDB Web Server
An easy to use, not secured web server, because I don't like the other options, and I like to create my own solutions most of the time.

## Table of content
|        Section Name         |
|:---------------------------:|
| [Usage](#usage)             |
| [Get handler](#get-handler) |
| [Put Handler](#put-handler) |
| [Data](#data)               |

## Usage

To start using this HTTP Server, import the `HTMLServer` class, and initialize it.

```python
from smdb_web_server import HTMLServer, UrlData
server = HTMLServer("127.0.0.1", 8080, title="Example server")
```

An `smdb_logger` can be used, if desired, but not neccesery.

To add a new url path, use the `add_url_rule` command.

```python
def index_handler(url_data: UrlData) -> str:
    ...

server.add_url_rule("/", index_handler)
```

This method will be called with a `GET` request by default. This can be set as an optional parameter called `protocol`. For now, only `GET` and `PUT` are supported.

Url handlers can be assigned with a decorator as well:

```python
@server.as_url_rule("/help")
def help_handler(url_data: UrlData) -> str:
    ...
```

To start the server, use either the `serve_forever` or the `serve_forever_threaded` function. The first will be a blocking call, the second will create a new thread.

```python
server.serve_forever_threaded(template_dictionary, static_dictionary, "Example Thread")
```

Both handlers can fail with [KnownError](#knownerror) exception, whitch will result in a user controlled return code and reason.

## GET handler

This handler can return any string, but it's usefull, if it returns an HTML file as string. This can be a hardcoded HTML code, or a static or dynamic file. For rendering HTML template files, the server has a helper function called `render_template_file`. This can render an HTML file from a pre setup dictionary.

```python
def index_handler(url_data: UrlData) -> str:
    example_list = ["value1", "value2|False", "value3|True"]
    return server.render_template("index", page_title="Example Title", example_selector=example_list, button_1="Button 1 name", button_2="Button 2 name")
```

If you need to just create a list to update an already rendered HTML page's selector, you can use it the following way:

```python
def update(url_data: UrlData):
    return server.render_template_list("example_selector", ["value1|True", "value2|False", "value3|False"])

server.add_url_rule("/update", update)
```

This will result in the following list, if we use the `option` tag as shown in the [template_dictionary](#template-dictionary) in the [data](#data) paragraph:

```HTML
<option disabled></option>
<option value="value1" selected>value1</option>
<option value="value2">value2</option>
<option value="value3">value3</option>
```

This list will be sent as a `plaintext` response.

## Put Handler

This handler can return a simple string. The incoming data will be a bytearray of the body of the request.
```python
from smdb_web_server import Protocol

def put_handler(url_data: UrlData) -> str:
    # Do stuff here.
    # Either return with string, or fail with KnownError
    ...

server.add_url_rule("/put", put_handler, Protocol.Put)
```

## Data

### Template dictionary
 - Keys: The "file name" without extention
 - Value: The file's content, or a path in the following format: "PATH|{Relative path to file}"

This dictionary will be used to generate HTML response from the template. Theese templates can have replaceable values with the following format.
```HTML
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ page_title }}</title>
    <link rel="stylesheet" href="/static/style.css">
</head>
<body>
    <div class="container">
        <h2>Example Header</h2>
        <div class="grid-container">
                <label for="ExampleSelector">Example Selector:</label>
                <select id="ExampleSelector" class="fixed-width">
                    {{[ example_selector ]}}
                </select>
            <div class="button-group">
                <button id="ExampleButton1">{{ button_1 }}</button>
                <button id="ExampleButton2">{{ button_2 }}</button>
            </div>
        </div>
    </div>
    <script src="/static/script.js"></script>
</body>
</html>
```

In this page the `{{ page_title }}`, the `{{ button_1 }}` and the `{{ button_2 }}` will be replaced with one value, and the `{{[ ExampleSelector ]}}` will be generated using a list.

This dictionary should contain a key-value pair with the value being a repeateable value to fill the `{{[ ExampleSelector ]}}` place.

```python
selector_values = """<option value="{{VALUE}}"{{SELECTED}}>{{VALUE}}</option>"""
```

Here, the `{{VALUE}}` will be replaced by the list's content, and the `{{SELECTED}}` will be replaced by either the value `selected` or with an emty string, if the list's value is formatted in the following manner: `{value}|True`. If the value following the `|` character is not "True", it will be treated as if it was not present.

You can return a list by calling the `render_template_list` function by itself, or by rendering a full HTML page by calling `render_template`, with a list as an argument.

### Static dictionary
 - Keys: The "file name" without extention
 - Value: Either the file's content, or a path in the following format: "PATH|{Relative path to file}"

Static files will be sent automatically, if the correct URL is called. In the [Template Dictionary](#template-dictionary) example, the javascript and the css files are loaded from the path `/static/{file_name}`. This will result in the `{file_name}` file being served from the dictionary.

### KnownError

This error is used to send a usercontrolled response code to the requester. This exception can be used the following way:

```python
from smdb_web_server import KnownError
def fail(_):
    raise KnownError("Reason", 405)
```

### Protocol

This is a simple enum class to use with `add_url_rule` to determine the protocol to be used

Values: `Get`, `Put`

### UrlData

This dataclass contains the following fields, either filled or containing `None`:

 - fragment: `String` object (Data following the `#` in the URL)
 - query: `Dictionary` with string keys and values (Data following the `?` in the URL). The key will be the part following the `?` or `&` characters, and the value will be the part after the `=` sign. If there is no value, `None` will be used as a value in the dictionary.
 - data: `Bytes` object (Payload of the request, if available)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/NightKey/smdb-server",
    "name": "smdb-web-server",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": null,
    "author": "Janth\u00f3 D\u00e1vid",
    "author_email": "davidjantho@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/21/86/02fe6dc41544276027b02b238974c3de096dec43b74ffa3f6d9d8d1bf58a/smdb_web_server-0.3.3.tar.gz",
    "platform": null,
    "description": "# SMDB Web Server\r\nAn easy to use, not secured web server, because I don't like the other options, and I like to create my own solutions most of the time.\r\n\r\n## Table of content\r\n|        Section Name         |\r\n|:---------------------------:|\r\n| [Usage](#usage)             |\r\n| [Get handler](#get-handler) |\r\n| [Put Handler](#put-handler) |\r\n| [Data](#data)               |\r\n\r\n## Usage\r\n\r\nTo start using this HTTP Server, import the `HTMLServer` class, and initialize it.\r\n\r\n```python\r\nfrom smdb_web_server import HTMLServer, UrlData\r\nserver = HTMLServer(\"127.0.0.1\", 8080, title=\"Example server\")\r\n```\r\n\r\nAn `smdb_logger` can be used, if desired, but not neccesery.\r\n\r\nTo add a new url path, use the `add_url_rule` command.\r\n\r\n```python\r\ndef index_handler(url_data: UrlData) -> str:\r\n    ...\r\n\r\nserver.add_url_rule(\"/\", index_handler)\r\n```\r\n\r\nThis method will be called with a `GET` request by default. This can be set as an optional parameter called `protocol`. For now, only `GET` and `PUT` are supported.\r\n\r\nUrl handlers can be assigned with a decorator as well:\r\n\r\n```python\r\n@server.as_url_rule(\"/help\")\r\ndef help_handler(url_data: UrlData) -> str:\r\n    ...\r\n```\r\n\r\nTo start the server, use either the `serve_forever` or the `serve_forever_threaded` function. The first will be a blocking call, the second will create a new thread.\r\n\r\n```python\r\nserver.serve_forever_threaded(template_dictionary, static_dictionary, \"Example Thread\")\r\n```\r\n\r\nBoth handlers can fail with [KnownError](#knownerror) exception, whitch will result in a user controlled return code and reason.\r\n\r\n## GET handler\r\n\r\nThis handler can return any string, but it's usefull, if it returns an HTML file as string. This can be a hardcoded HTML code, or a static or dynamic file. For rendering HTML template files, the server has a helper function called `render_template_file`. This can render an HTML file from a pre setup dictionary.\r\n\r\n```python\r\ndef index_handler(url_data: UrlData) -> str:\r\n    example_list = [\"value1\", \"value2|False\", \"value3|True\"]\r\n    return server.render_template(\"index\", page_title=\"Example Title\", example_selector=example_list, button_1=\"Button 1 name\", button_2=\"Button 2 name\")\r\n```\r\n\r\nIf you need to just create a list to update an already rendered HTML page's selector, you can use it the following way:\r\n\r\n```python\r\ndef update(url_data: UrlData):\r\n    return server.render_template_list(\"example_selector\", [\"value1|True\", \"value2|False\", \"value3|False\"])\r\n\r\nserver.add_url_rule(\"/update\", update)\r\n```\r\n\r\nThis will result in the following list, if we use the `option` tag as shown in the [template_dictionary](#template-dictionary) in the [data](#data) paragraph:\r\n\r\n```HTML\r\n<option disabled></option>\r\n<option value=\"value1\" selected>value1</option>\r\n<option value=\"value2\">value2</option>\r\n<option value=\"value3\">value3</option>\r\n```\r\n\r\nThis list will be sent as a `plaintext` response.\r\n\r\n## Put Handler\r\n\r\nThis handler can return a simple string. The incoming data will be a bytearray of the body of the request.\r\n```python\r\nfrom smdb_web_server import Protocol\r\n\r\ndef put_handler(url_data: UrlData) -> str:\r\n    # Do stuff here.\r\n    # Either return with string, or fail with KnownError\r\n    ...\r\n\r\nserver.add_url_rule(\"/put\", put_handler, Protocol.Put)\r\n```\r\n\r\n## Data\r\n\r\n### Template dictionary\r\n - Keys: The \"file name\" without extention\r\n - Value: The file's content, or a path in the following format: \"PATH|{Relative path to file}\"\r\n\r\nThis dictionary will be used to generate HTML response from the template. Theese templates can have replaceable values with the following format.\r\n```HTML\r\n<html lang=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>{{ page_title }}</title>\r\n    <link rel=\"stylesheet\" href=\"/static/style.css\">\r\n</head>\r\n<body>\r\n    <div class=\"container\">\r\n        <h2>Example Header</h2>\r\n        <div class=\"grid-container\">\r\n                <label for=\"ExampleSelector\">Example Selector:</label>\r\n                <select id=\"ExampleSelector\" class=\"fixed-width\">\r\n                    {{[ example_selector ]}}\r\n                </select>\r\n            <div class=\"button-group\">\r\n                <button id=\"ExampleButton1\">{{ button_1 }}</button>\r\n                <button id=\"ExampleButton2\">{{ button_2 }}</button>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <script src=\"/static/script.js\"></script>\r\n</body>\r\n</html>\r\n```\r\n\r\nIn this page the `{{ page_title }}`, the `{{ button_1 }}` and the `{{ button_2 }}` will be replaced with one value, and the `{{[ ExampleSelector ]}}` will be generated using a list.\r\n\r\nThis dictionary should contain a key-value pair with the value being a repeateable value to fill the `{{[ ExampleSelector ]}}` place.\r\n\r\n```python\r\nselector_values = \"\"\"<option value=\"{{VALUE}}\"{{SELECTED}}>{{VALUE}}</option>\"\"\"\r\n```\r\n\r\nHere, the `{{VALUE}}` will be replaced by the list's content, and the `{{SELECTED}}` will be replaced by either the value `selected` or with an emty string, if the list's value is formatted in the following manner: `{value}|True`. If the value following the `|` character is not \"True\", it will be treated as if it was not present.\r\n\r\nYou can return a list by calling the `render_template_list` function by itself, or by rendering a full HTML page by calling `render_template`, with a list as an argument.\r\n\r\n### Static dictionary\r\n - Keys: The \"file name\" without extention\r\n - Value: Either the file's content, or a path in the following format: \"PATH|{Relative path to file}\"\r\n\r\nStatic files will be sent automatically, if the correct URL is called. In the [Template Dictionary](#template-dictionary) example, the javascript and the css files are loaded from the path `/static/{file_name}`. This will result in the `{file_name}` file being served from the dictionary.\r\n\r\n### KnownError\r\n\r\nThis error is used to send a usercontrolled response code to the requester. This exception can be used the following way:\r\n\r\n```python\r\nfrom smdb_web_server import KnownError\r\ndef fail(_):\r\n    raise KnownError(\"Reason\", 405)\r\n```\r\n\r\n### Protocol\r\n\r\nThis is a simple enum class to use with `add_url_rule` to determine the protocol to be used\r\n\r\nValues: `Get`, `Put`\r\n\r\n### UrlData\r\n\r\nThis dataclass contains the following fields, either filled or containing `None`:\r\n\r\n - fragment: `String` object (Data following the `#` in the URL)\r\n - query: `Dictionary` with string keys and values (Data following the `?` in the URL). The key will be the part following the `?` or `&` characters, and the value will be the part after the `=` sign. If there is no value, `None` will be used as a value in the dictionary.\r\n - data: `Bytes` object (Payload of the request, if available)\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A really basic, not so safe web server.",
    "version": "0.3.3",
    "project_urls": {
        "Bug Tracker": "https://github.com/NightKey/smdb-server/issues",
        "Homepage": "https://github.com/NightKey/smdb-server"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "403fae2b293519058d787467f0a9dd9e25f7d4ba629fb2890cc1098d45e17f26",
                "md5": "08c93d4a6feb289ec0e5a8525756cb75",
                "sha256": "aff45a327a6ddc7382da26d0bdff37bbc1182617bd36af13aeb4d24ed8cc0941"
            },
            "downloads": -1,
            "filename": "smdb_web_server-0.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "08c93d4a6feb289ec0e5a8525756cb75",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 8266,
            "upload_time": "2024-05-16T14:31:04",
            "upload_time_iso_8601": "2024-05-16T14:31:04.811586Z",
            "url": "https://files.pythonhosted.org/packages/40/3f/ae2b293519058d787467f0a9dd9e25f7d4ba629fb2890cc1098d45e17f26/smdb_web_server-0.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "218602fe6dc41544276027b02b238974c3de096dec43b74ffa3f6d9d8d1bf58a",
                "md5": "a7bfd04e8134b1aedc54af8ce8315122",
                "sha256": "18046630da134d354c90fd47e9b876e303ffc589d4fadda10d44d7ab56db8c5c"
            },
            "downloads": -1,
            "filename": "smdb_web_server-0.3.3.tar.gz",
            "has_sig": false,
            "md5_digest": "a7bfd04e8134b1aedc54af8ce8315122",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 8192,
            "upload_time": "2024-05-16T14:31:06",
            "upload_time_iso_8601": "2024-05-16T14:31:06.108455Z",
            "url": "https://files.pythonhosted.org/packages/21/86/02fe6dc41544276027b02b238974c3de096dec43b74ffa3f6d9d8d1bf58a/smdb_web_server-0.3.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-16 14:31:06",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NightKey",
    "github_project": "smdb-server",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "smdb-web-server"
}
        
Elapsed time: 0.61166s