cmit


Namecmit JSON
Version 0.1.0 PyPI version JSON
download
home_page
SummaryA text-based protocol to support internal process communication (IPC) within a single node.
upload_time2023-12-17 07:55:26
maintainer
docs_urlNone
authorBigelow Systems, LLC.
requires_python>=3.6
licenseCopyright (c) 2023 Bigelow Systems, LLC and individual contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords ipc process communication text protocol cmit
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # CMIT-Python
**Version**: 0.1.0

This is a python implementation of the Common Messaging Interface Transport (CMIT) protocol.

As a protocol CMIT is designed to support internal process communication (IPC) within
a single node. Consequently, this current version only supports serving through a
UNIX domain socket. By default, CMIT supports 3 message command verbs (PING, EXECUTE, POLL).
However, CMIT is designed to be very flexible, and you may augment it with your own command verbs.

## Installation
```bash
pip install cmit
```

## Usage
Implementing a CMIT server can be very simple. A basic implementation is shown below. Another example can be
found in the `demo` directory.

```python
from cmit import server
SOCKET_PATH = "/tmp/cmit.sock"
demo_server = server.CMITServer(SOCKET_PATH, server.SimpleCMITRequestHandler)
demo_server.serve_forever()
```

**Note**: The default handler `SimpleCMITRequestHandler` will accept POLL and EXECUTE requests, the actual processing
of these requests is left up to the final implementation. That is, they are simply acknowledged.

## Rationale
I designed the CMIT protocol to handle communication between a webserver and a backend process. The backend process
was often a long-running process that would be invoked by the webserver when a request was received. Because the backend
process was long-running, it could not be invoked directly by the webserver or else the webserver would block. With CMIT,
the webserver could send a request to the backend process and continue processing other requests. The backend process
would then run in the background and send a response back to the webserver through the CMIT protocol when it was finished.
The additional benefit to taking this approach was that it didn't require any additional infrastructure such as a message
broker or cache. The CMIT protocol is designed to be very simple and lightweight, and is not intended to replace more
robust protocols such as AMQP or HTTP.

## Specification
The CMIT protocol is a simple text-based protocol. The protocol is designed to be flexible and extensible. If you
are already familiar with the HTTP protocol, you will find that CMIT is very similar in nature. 

### Request
The following describes the basic structure of a CMIT request.

```
<COMMAND> <VERSION>
<BLANK LINE>
<MESAAGE BODY>
<BLANK LINE>
```

A CMIT request is composed of a command verb, a version, and a message body. The command verb is a string that
identifies the type of request. The version is a string that identifies the version of the protocol. The message
body is a string that contains the actual message. Unlike HTTP, CMIT does not support headers and the message body
is not optional. In a plain CMIT request, the message body is a JSON object containing four fields: `id`, `timestamp`,
`topic`, and `payload`.

```json
{
"id": "f4dc4223403b22fbca286ec676717440", 
"timestamp": "1702712308.739593",
"topic": "test.handler",
"payload": {
"args": ["arg1", "arg2"], 
"kwargs": {"key1": "value1", "key2": "value2"}, 
"data": "some data"}
}
```

#### id
The `id` field is a string that uniquely identifies the message. The `id` field is used to match a response to a
request as well as assist in message deduplication, logging and storing message. When sending a request, the `id` field 
is optional, and will automatically be generated if not provided.

#### timestamp
The `timestamp` field is a string that identifies the time the message was sent. The `timestamp` field is optional and
will automatically be generated if not provided. If provided, the timestamp should be in POSIX time format.

#### topic
The `topic` field is a string that identifies the topic of the message. The `topic` is essentially a routing key that
is used to route the message to the appropriate handler. The `topic` field is required.

#### payload
The `payload` field can be any JSON serializable object such as a string, object, or list. The `payload` field is 
not required, however the default implementation of the `SimpleCMITRequestHandler` will append the `payload` field as
an object to both the request and response at a minimum.

### Response
The following describes the basic structure of a CMIT response.

```
<VERSION> <STATUS> <REASON>
<BLANK LINE>
<MESAAGE BODY>
<BLANK LINE>
```

A CMIT response is composed of a version, a status, a reason, and a message body. The version is a string that
identifies the version of the protocol. The status is a string that identifies the status of the response. The reason
is a string that provides a human-readable description of the status. The message body is a string that contains the
actual message. Just like the request, responses do not support headers and the message body is not optional and follows
the same general format of requests by containing a JSON object with the four fields: `id`, `timestamp`, `topic`, 
and `payload`.

The difference between a request and a response is that the `id` field is required in a response and must match the `id`
field of the request. The `timestamp` field should be the same as the request. The `topic` field should be the same as
the request. The `payload` field is optional and can be any JSON serializable object.

### Command Verbs
Command verbs are used to identify the type of request. The following command verbs are supported by default:
- PING
- EXECUTE
- POLL

However, you may add your own command verbs by extending the `CMITRequestHandler` with methods that match the command
verb. For example, if you wanted to add a command verb called `TEST`, you would add a method called `do_TEST` to your
handler. See the `demo/echo-server.py` file for an example on how to do this.


#### PING
The `PING` command verb is used to test the connection to the server. By default a `PING` request will return a response
with a copy of the request's `payload` field.

#### EXECUTE
The `EXECUTE` command verb is used to execute a command on the server. However, the default implementation of the
`SimpleCMITRequestHandler` does not actually execute any commands. Instead, it simply acknowledges the request and
returns a response with an ok status. The `EXECUTE` command verb is intended to be extended by the user to execute
scripts or commands on the server. This is the command verb that I use to execute commands on the backend process.

#### POLL
The `POLL` command verb is used to poll the server for messages. The default implementation of the 
`SimpleCMITRequestHandler` will return the length of the pending execution queue. This is the command verb that I use
to poll the backend process for messages.

### Final Notes
Like I said before, the CMIT protocol is designed to be very simple and lightweight. Its design is inspired by a
particular need I had, and I hope that it can be useful to others. If you have any questions or suggestions, please
feel free to open an issue or submit a pull request. I might at some point add more robust documentation, but for now
I think this is sufficient.

## Acknowledgements
I pulled a lot of inspiration from the HTTP protocol, and I also used the `BaseHTTPRequestHandler` class from the
`http.server` module as a starting point for the `CMITRequestHandler` class. I also used the `socketserver` module
to implement the `CMITServer` class. Finally, I based the `cmit.request` module on the `requests` library. All of these
ideas were of course modified to fit the needs of the CMIT protocol, but I wanted to acknowledge them nonetheless.

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "cmit",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "ipc,process,communication,text,protocol,cmit",
    "author": "Bigelow Systems, LLC.",
    "author_email": "Jordan Bigelow <jordan@jordanbigelow.com>, Bigelow Systems <engineering+cmit@bigelow.systems>",
    "download_url": "https://files.pythonhosted.org/packages/53/e0/06f6b192866448582a17de8f39efacba2d1c52a4e2d44b898feb52e86759/cmit-0.1.0.tar.gz",
    "platform": null,
    "description": "# CMIT-Python\n**Version**: 0.1.0\n\nThis is a python implementation of the Common Messaging Interface Transport (CMIT) protocol.\n\nAs a protocol CMIT is designed to support internal process communication (IPC) within\na single node. Consequently, this current version only supports serving through a\nUNIX domain socket. By default, CMIT supports 3 message command verbs (PING, EXECUTE, POLL).\nHowever, CMIT is designed to be very flexible, and you may augment it with your own command verbs.\n\n## Installation\n```bash\npip install cmit\n```\n\n## Usage\nImplementing a CMIT server can be very simple. A basic implementation is shown below. Another example can be\nfound in the `demo` directory.\n\n```python\nfrom cmit import server\nSOCKET_PATH = \"/tmp/cmit.sock\"\ndemo_server = server.CMITServer(SOCKET_PATH, server.SimpleCMITRequestHandler)\ndemo_server.serve_forever()\n```\n\n**Note**: The default handler `SimpleCMITRequestHandler` will accept POLL and EXECUTE requests, the actual processing\nof these requests is left up to the final implementation. That is, they are simply acknowledged.\n\n## Rationale\nI designed the CMIT protocol to handle communication between a webserver and a backend process. The backend process\nwas often a long-running process that would be invoked by the webserver when a request was received. Because the backend\nprocess was long-running, it could not be invoked directly by the webserver or else the webserver would block. With CMIT,\nthe webserver could send a request to the backend process and continue processing other requests. The backend process\nwould then run in the background and send a response back to the webserver through the CMIT protocol when it was finished.\nThe additional benefit to taking this approach was that it didn't require any additional infrastructure such as a message\nbroker or cache. The CMIT protocol is designed to be very simple and lightweight, and is not intended to replace more\nrobust protocols such as AMQP or HTTP.\n\n## Specification\nThe CMIT protocol is a simple text-based protocol. The protocol is designed to be flexible and extensible. If you\nare already familiar with the HTTP protocol, you will find that CMIT is very similar in nature. \n\n### Request\nThe following describes the basic structure of a CMIT request.\n\n```\n<COMMAND> <VERSION>\n<BLANK LINE>\n<MESAAGE BODY>\n<BLANK LINE>\n```\n\nA CMIT request is composed of a command verb, a version, and a message body. The command verb is a string that\nidentifies the type of request. The version is a string that identifies the version of the protocol. The message\nbody is a string that contains the actual message. Unlike HTTP, CMIT does not support headers and the message body\nis not optional. In a plain CMIT request, the message body is a JSON object containing four fields: `id`, `timestamp`,\n`topic`, and `payload`.\n\n```json\n{\n\"id\": \"f4dc4223403b22fbca286ec676717440\", \n\"timestamp\": \"1702712308.739593\",\n\"topic\": \"test.handler\",\n\"payload\": {\n\"args\": [\"arg1\", \"arg2\"], \n\"kwargs\": {\"key1\": \"value1\", \"key2\": \"value2\"}, \n\"data\": \"some data\"}\n}\n```\n\n#### id\nThe `id` field is a string that uniquely identifies the message. The `id` field is used to match a response to a\nrequest as well as assist in message deduplication, logging and storing message. When sending a request, the `id` field \nis optional, and will automatically be generated if not provided.\n\n#### timestamp\nThe `timestamp` field is a string that identifies the time the message was sent. The `timestamp` field is optional and\nwill automatically be generated if not provided. If provided, the timestamp should be in POSIX time format.\n\n#### topic\nThe `topic` field is a string that identifies the topic of the message. The `topic` is essentially a routing key that\nis used to route the message to the appropriate handler. The `topic` field is required.\n\n#### payload\nThe `payload` field can be any JSON serializable object such as a string, object, or list. The `payload` field is \nnot required, however the default implementation of the `SimpleCMITRequestHandler` will append the `payload` field as\nan object to both the request and response at a minimum.\n\n### Response\nThe following describes the basic structure of a CMIT response.\n\n```\n<VERSION> <STATUS> <REASON>\n<BLANK LINE>\n<MESAAGE BODY>\n<BLANK LINE>\n```\n\nA CMIT response is composed of a version, a status, a reason, and a message body. The version is a string that\nidentifies the version of the protocol. The status is a string that identifies the status of the response. The reason\nis a string that provides a human-readable description of the status. The message body is a string that contains the\nactual message. Just like the request, responses do not support headers and the message body is not optional and follows\nthe same general format of requests by containing a JSON object with the four fields: `id`, `timestamp`, `topic`, \nand `payload`.\n\nThe difference between a request and a response is that the `id` field is required in a response and must match the `id`\nfield of the request. The `timestamp` field should be the same as the request. The `topic` field should be the same as\nthe request. The `payload` field is optional and can be any JSON serializable object.\n\n### Command Verbs\nCommand verbs are used to identify the type of request. The following command verbs are supported by default:\n- PING\n- EXECUTE\n- POLL\n\nHowever, you may add your own command verbs by extending the `CMITRequestHandler` with methods that match the command\nverb. For example, if you wanted to add a command verb called `TEST`, you would add a method called `do_TEST` to your\nhandler. See the `demo/echo-server.py` file for an example on how to do this.\n\n\n#### PING\nThe `PING` command verb is used to test the connection to the server. By default a `PING` request will return a response\nwith a copy of the request's `payload` field.\n\n#### EXECUTE\nThe `EXECUTE` command verb is used to execute a command on the server. However, the default implementation of the\n`SimpleCMITRequestHandler` does not actually execute any commands. Instead, it simply acknowledges the request and\nreturns a response with an ok status. The `EXECUTE` command verb is intended to be extended by the user to execute\nscripts or commands on the server. This is the command verb that I use to execute commands on the backend process.\n\n#### POLL\nThe `POLL` command verb is used to poll the server for messages. The default implementation of the \n`SimpleCMITRequestHandler` will return the length of the pending execution queue. This is the command verb that I use\nto poll the backend process for messages.\n\n### Final Notes\nLike I said before, the CMIT protocol is designed to be very simple and lightweight. Its design is inspired by a\nparticular need I had, and I hope that it can be useful to others. If you have any questions or suggestions, please\nfeel free to open an issue or submit a pull request. I might at some point add more robust documentation, but for now\nI think this is sufficient.\n\n## Acknowledgements\nI pulled a lot of inspiration from the HTTP protocol, and I also used the `BaseHTTPRequestHandler` class from the\n`http.server` module as a starting point for the `CMITRequestHandler` class. I also used the `socketserver` module\nto implement the `CMITServer` class. Finally, I based the `cmit.request` module on the `requests` library. All of these\nideas were of course modified to fit the needs of the CMIT protocol, but I wanted to acknowledge them nonetheless.\n",
    "bugtrack_url": null,
    "license": "Copyright (c) 2023 Bigelow Systems, LLC and individual contributors. All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \u201cAS IS\u201d AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
    "summary": "A text-based protocol to support internal process communication (IPC) within a single node.",
    "version": "0.1.0",
    "project_urls": {
        "Homepage": "https://github.com/bigelow-systems/cmit",
        "Issues": "https://github.com/bigelow-systems/cmit/issues"
    },
    "split_keywords": [
        "ipc",
        "process",
        "communication",
        "text",
        "protocol",
        "cmit"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "947d578baac6bf25ed7f714e8517a23fc77a675a116b4f4ebd1945524544bf79",
                "md5": "180d6a4eb9c1e4ceeeeb84298b2f7749",
                "sha256": "2615d651b14b6aaea583bb8adb5ccd0a3580b9603268b0f19572ca6e9eea20be"
            },
            "downloads": -1,
            "filename": "cmit-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "180d6a4eb9c1e4ceeeeb84298b2f7749",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 26895,
            "upload_time": "2023-12-17T07:55:24",
            "upload_time_iso_8601": "2023-12-17T07:55:24.821444Z",
            "url": "https://files.pythonhosted.org/packages/94/7d/578baac6bf25ed7f714e8517a23fc77a675a116b4f4ebd1945524544bf79/cmit-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "53e006f6b192866448582a17de8f39efacba2d1c52a4e2d44b898feb52e86759",
                "md5": "f263dca0ecd56021de291190cb28d0d1",
                "sha256": "4914e7799fefef4aa6dfce71eb6da068a247108a6c10eb7a05ac0c15f0160406"
            },
            "downloads": -1,
            "filename": "cmit-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f263dca0ecd56021de291190cb28d0d1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 25377,
            "upload_time": "2023-12-17T07:55:26",
            "upload_time_iso_8601": "2023-12-17T07:55:26.590565Z",
            "url": "https://files.pythonhosted.org/packages/53/e0/06f6b192866448582a17de8f39efacba2d1c52a4e2d44b898feb52e86759/cmit-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-17 07:55:26",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "bigelow-systems",
    "github_project": "cmit",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "cmit"
}
        
Elapsed time: 0.15058s