cmdbox


Namecmdbox JSON
Version 0.2.7.3 PyPI version JSON
download
home_pagehttps://github.com/hamacom2004jp/cmdbox
Summarycmdbox: It is a command line application with a plugin mechanism.
upload_time2025-01-11 14:05:19
maintainerhamacom2004jp
docs_urlNone
authorhamacom2004jp
requires_python>=3.8
licenseMIT
keywords cli restapi redis fastapi
VCS
bugtrack_url
requirements argcomplete collectlicense cryptography fastapi gevent itsdangerous numpy Pillow python-multipart redis requests six sphinx sphinx-rtd-theme sphinx_fontawesome sphinx-intl sphinx-sitemap tabulate twine uvicorn wheel
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # cmdbox

- It is a command line application with a plugin mechanism.
- Documentation is [here](https://hamacom2004jp.github.io/cmdbox/).
- With cmdbox, you can easily implement commands with complex options.
- The implemented commands can be called from the CLI / RESTAPI / Web screen.
- The implemented commands can be executed on a remote server via redis.

# Install

- Install cmdbox with the following command.

```bash
pip install cmdbox
cmdbox -v
```

- Also install the docker version of the redis server.

```bash
docker run -p 6379:6379 --name redis -it ubuntu/redis:latest
```

# Tutorial

- Open the ```.sample/sample_project``` folder in the current directory with VSCode.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme001.png)

- Install dependent libraries.

```bash
python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
```

- Run the project.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme002.png)

- The localhost web screen will open.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme003.png)

- Enter ```user01 / user01``` for the initial ID and PW to sign in.
- Using this web screen, you can easily execute the commands implemented in cmdbox.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme004.png)

- Let's look at the command to get a list of files as an example.
- Press the plus button under Commands to open the Add dialog.
- Then enter the following.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme005.png)

- Press the ```Save``` button once and then press the ```Execute``` button.
- The results of the command execution are displayed.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme006.png)

- Open the saved ```client_time``` and press the ```Raw``` button.
- You will see how to execute the same command on the command line; the RESTAPI URL is also displayed.

![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme007.png)


## How to implement a new command using cmdbox

- Under the ```sample/app/features/cli``` folder, you will find an implementation of the ```client_time``` mentioned earlier.
- The implementation is as follows. (Slightly abbreviated display)
- Create the following code and save it in the ```sample/app/features/cli``` folder.

```python
from cmdbox.app import common, feature
from typing import Dict, Any, Tuple, Union, List
import argparse
import datetime
import logging


class ClientTime(feature.Feature):
    def get_mode(self) -> Union[str, List[str]]:
        return "client"

    def get_cmd(self):
        return 'time'

    def get_option(self):
        return dict(
            type="str", default=None, required=False, multi=False, hide=False, use_redis=self.USE_REDIS_FALSE,
            discription_ja="クライアント側の現在時刻を表示します。",
            discription_en="Displays the current time at the client side.",
            choice=[
                dict(opt="timedelta", type="int", default=9, required=False, multi=False, hide=False, choice=None,
                        discription_ja="時差の時間数を指定します。",
                        discription_en="Specify the number of hours of time difference."),
            ])

    def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
        tz = datetime.timezone(datetime.timedelta(hours=args.timedelta))
        dt = datetime.datetime.now(tz)
        ret = dict(success=dict(data=dt.strftime('%Y-%m-%d %H:%M:%S')))
        common.print_format(ret, args.format, tm, args.output_json, args.output_json_append, pf=pf)
        if 'success' not in ret:
            return 1, ret, None
        return 0, ret, None
```

- Open the file ```sample/extensions/features.yml```. The file should look something like this.
- This file specifies where new commands are to be read.
- For example, if you want to add a package to read, add a new ```package``` and ```prefix``` to ```features.cli```.
- Note that ```features.web``` can be used to add a new web screen.
- If you only want to call commands added in ```features.cli``` via RESTAPI, no additional implementation is needed in ```features.web```.


```yml
features:
  cli:
    - package: sample.app.features.cli
      prefix: sample_
  web:
    - package: sample.app.features.web
      prefix: sample_web_
args:
  cli:
    - rule:
        mode: web
      default:
      coercion:
        assets:
          - f"{Path(self.ver.__file__).parent / 'web' / 'assets'}"
        doc_root: f"{Path(self.ver.__file__).parent / 'web'}"
    - rule:
        mode: gui
      default:
      coercion:
        assets:
          - f"{Path(self.ver.__file__).parent / 'web' / 'assets'}"
        doc_root: f"{Path(self.ver.__file__).parent / 'web'}"
```

- The following files should also be known when using commands on the web screen or RESTAPI.
- Open the file ```sample/extensions/user_list.yml```. The file should look something like this.
- This file manages the users and groups that are allowed Web access and their rules.
- The rule of the previous command is ```allow``` for users in the ```user``` group in ```cmdrule.rules```.


```yml
users:
- uid: 1
  name: admin
  password: XXXXXXXXXXX
  hash: plain
  groups: [admin]
  email: admin@aaa.bbb.jp
- uid: 101
  name: user01
  password: XXXXXXXXXXX
  hash: md5
  groups: [user]
  email: user01@aaa.bbb.jp
- uid: 102
  name: user02
  password: XXXXXXXXXXX
  hash: sha1
  groups: [readonly]
  email: user02@aaa.bbb.jp
- uid: 103
  name: user03
  password: XXXXXXXXXXX
  hash: sha256
  groups: [editor]
  email: user03@aaa.bbb.jp
groups:
- gid: 1
  name: admin
- gid: 101
  name: user
- gid: 102
  name: readonly
  parent: user
- gid: 103
  name: editor
  parent: user
cmdrule:
  policy: deny # allow, deny
  rules:
  - groups: [admin]
    rule: allow
  - groups: [user]
    mode: client
    cmds: [file_download, file_list, server_info]
    rule: allow
  - groups: [user]
    mode: server
    cmds: [list]
    rule: allow
  - groups: [editor]
    mode: client
    cmds: [file_copy, file_mkdir, file_move, file_remove, file_rmdir, file_upload]
    rule: allow
pathrule:
  policy: deny # allow, deny
  rules:
  - groups: [admin]
    paths: [/]
    rule: allow
  - groups: [user]
    paths: [/signin, /assets, /bbforce_cmd, /copyright, /dosignin, /dosignout,
            /exec_cmd, /exec_pipe, /filer, /gui, /get_server_opt, /usesignout, /versions_cmdbox, /versions_used]
    rule: allow
  - groups: [readonly]
    paths: [/gui/del_cmd, /gui/del_pipe, /gui/save_cmd, /gui/save_pipe]
    rule: deny
  - groups: [editor]
    paths: [/gui/del_cmd, /gui/del_pipe, /gui/save_cmd, /gui/save_pipe]
    rule: allow
oauth2:
  providers:
    google:
      enabled: false
      client_id: XXXXXXXXXXX
      client_secret: XXXXXXXXXXX
      redirect_uri: https://localhost:8443/oauth2/google/callback
      scope: ['email']
      note:
      - https://developers.google.com/identity/protocols/oauth2/web-server?hl=ja#httprest
    github:
      enabled: false
      client_id: XXXXXXXXXXX
      client_secret: XXXXXXXXXXX
      redirect_uri: https://localhost:8443/oauth2/github/callback
      scope: ['user:email']
      note:
      - https://docs.github.com/ja/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#scopes
```

- See the documentation for references to each file.
- Documentation is [here](https://hamacom2004jp.github.io/cmdbox/).


# Lisence

This project is licensed under the MIT License, see the LICENSE file for details



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/hamacom2004jp/cmdbox",
    "name": "cmdbox",
    "maintainer": "hamacom2004jp",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "hamacom2004jp@gmail.com",
    "keywords": "cli restapi redis fastapi",
    "author": "hamacom2004jp",
    "author_email": "hamacom2004jp@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/94/e3/832c3222da122d6d6c148c8d3be0068bf92ca636fbe4764c7c1f4fc2cb05/cmdbox-0.2.7.3.tar.gz",
    "platform": null,
    "description": "# cmdbox\r\n\r\n- It is a command line application with a plugin mechanism.\r\n- Documentation is [here](https://hamacom2004jp.github.io/cmdbox/).\r\n- With cmdbox, you can easily implement commands with complex options.\r\n- The implemented commands can be called from the CLI / RESTAPI / Web screen.\r\n- The implemented commands can be executed on a remote server via redis.\r\n\r\n# Install\r\n\r\n- Install cmdbox with the following command.\r\n\r\n```bash\r\npip install cmdbox\r\ncmdbox -v\r\n```\r\n\r\n- Also install the docker version of the redis server.\r\n\r\n```bash\r\ndocker run -p 6379:6379 --name redis -it ubuntu/redis:latest\r\n```\r\n\r\n# Tutorial\r\n\r\n- Open the ```.sample/sample_project``` folder in the current directory with VSCode.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme001.png)\r\n\r\n- Install dependent libraries.\r\n\r\n```bash\r\npython -m venv .venv\r\n. .venv/bin/activate\r\npip install -r requirements.txt\r\n```\r\n\r\n- Run the project.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme002.png)\r\n\r\n- The localhost web screen will open.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme003.png)\r\n\r\n- Enter ```user01 / user01``` for the initial ID and PW to sign in.\r\n- Using this web screen, you can easily execute the commands implemented in cmdbox.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme004.png)\r\n\r\n- Let's look at the command to get a list of files as an example.\r\n- Press the plus button under Commands to open the Add dialog.\r\n- Then enter the following.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme005.png)\r\n\r\n- Press the ```Save``` button once and then press the ```Execute``` button.\r\n- The results of the command execution are displayed.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme006.png)\r\n\r\n- Open the saved ```client_time``` and press the ```Raw``` button.\r\n- You will see how to execute the same command on the command line; the RESTAPI URL is also displayed.\r\n\r\n![image](https://github.com/hamacom2004jp/cmdbox/raw/main/docs_src/static/ss/readme007.png)\r\n\r\n\r\n## How to implement a new command using cmdbox\r\n\r\n- Under the ```sample/app/features/cli``` folder, you will find an implementation of the ```client_time``` mentioned earlier.\r\n- The implementation is as follows. (Slightly abbreviated display)\r\n- Create the following code and save it in the ```sample/app/features/cli``` folder.\r\n\r\n```python\r\nfrom cmdbox.app import common, feature\r\nfrom typing import Dict, Any, Tuple, Union, List\r\nimport argparse\r\nimport datetime\r\nimport logging\r\n\r\n\r\nclass ClientTime(feature.Feature):\r\n    def get_mode(self) -> Union[str, List[str]]:\r\n        return \"client\"\r\n\r\n    def get_cmd(self):\r\n        return 'time'\r\n\r\n    def get_option(self):\r\n        return dict(\r\n            type=\"str\", default=None, required=False, multi=False, hide=False, use_redis=self.USE_REDIS_FALSE,\r\n            discription_ja=\"\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\u306e\u73fe\u5728\u6642\u523b\u3092\u8868\u793a\u3057\u307e\u3059\u3002\",\r\n            discription_en=\"Displays the current time at the client side.\",\r\n            choice=[\r\n                dict(opt=\"timedelta\", type=\"int\", default=9, required=False, multi=False, hide=False, choice=None,\r\n                        discription_ja=\"\u6642\u5dee\u306e\u6642\u9593\u6570\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\",\r\n                        discription_en=\"Specify the number of hours of time difference.\"),\r\n            ])\r\n\r\n    def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:\r\n        tz = datetime.timezone(datetime.timedelta(hours=args.timedelta))\r\n        dt = datetime.datetime.now(tz)\r\n        ret = dict(success=dict(data=dt.strftime('%Y-%m-%d %H:%M:%S')))\r\n        common.print_format(ret, args.format, tm, args.output_json, args.output_json_append, pf=pf)\r\n        if 'success' not in ret:\r\n            return 1, ret, None\r\n        return 0, ret, None\r\n```\r\n\r\n- Open the file ```sample/extensions/features.yml```. The file should look something like this.\r\n- This file specifies where new commands are to be read.\r\n- For example, if you want to add a package to read, add a new ```package``` and ```prefix``` to ```features.cli```.\r\n- Note that ```features.web``` can be used to add a new web screen.\r\n- If you only want to call commands added in ```features.cli``` via RESTAPI, no additional implementation is needed in ```features.web```.\r\n\r\n\r\n```yml\r\nfeatures:\r\n  cli:\r\n    - package: sample.app.features.cli\r\n      prefix: sample_\r\n  web:\r\n    - package: sample.app.features.web\r\n      prefix: sample_web_\r\nargs:\r\n  cli:\r\n    - rule:\r\n        mode: web\r\n      default:\r\n      coercion:\r\n        assets:\r\n          - f\"{Path(self.ver.__file__).parent / 'web' / 'assets'}\"\r\n        doc_root: f\"{Path(self.ver.__file__).parent / 'web'}\"\r\n    - rule:\r\n        mode: gui\r\n      default:\r\n      coercion:\r\n        assets:\r\n          - f\"{Path(self.ver.__file__).parent / 'web' / 'assets'}\"\r\n        doc_root: f\"{Path(self.ver.__file__).parent / 'web'}\"\r\n```\r\n\r\n- The following files should also be known when using commands on the web screen or RESTAPI.\r\n- Open the file ```sample/extensions/user_list.yml```. The file should look something like this.\r\n- This file manages the users and groups that are allowed Web access and their rules.\r\n- The rule of the previous command is ```allow``` for users in the ```user``` group in ```cmdrule.rules```.\r\n\r\n\r\n```yml\r\nusers:\r\n- uid: 1\r\n  name: admin\r\n  password: XXXXXXXXXXX\r\n  hash: plain\r\n  groups: [admin]\r\n  email: admin@aaa.bbb.jp\r\n- uid: 101\r\n  name: user01\r\n  password: XXXXXXXXXXX\r\n  hash: md5\r\n  groups: [user]\r\n  email: user01@aaa.bbb.jp\r\n- uid: 102\r\n  name: user02\r\n  password: XXXXXXXXXXX\r\n  hash: sha1\r\n  groups: [readonly]\r\n  email: user02@aaa.bbb.jp\r\n- uid: 103\r\n  name: user03\r\n  password: XXXXXXXXXXX\r\n  hash: sha256\r\n  groups: [editor]\r\n  email: user03@aaa.bbb.jp\r\ngroups:\r\n- gid: 1\r\n  name: admin\r\n- gid: 101\r\n  name: user\r\n- gid: 102\r\n  name: readonly\r\n  parent: user\r\n- gid: 103\r\n  name: editor\r\n  parent: user\r\ncmdrule:\r\n  policy: deny # allow, deny\r\n  rules:\r\n  - groups: [admin]\r\n    rule: allow\r\n  - groups: [user]\r\n    mode: client\r\n    cmds: [file_download, file_list, server_info]\r\n    rule: allow\r\n  - groups: [user]\r\n    mode: server\r\n    cmds: [list]\r\n    rule: allow\r\n  - groups: [editor]\r\n    mode: client\r\n    cmds: [file_copy, file_mkdir, file_move, file_remove, file_rmdir, file_upload]\r\n    rule: allow\r\npathrule:\r\n  policy: deny # allow, deny\r\n  rules:\r\n  - groups: [admin]\r\n    paths: [/]\r\n    rule: allow\r\n  - groups: [user]\r\n    paths: [/signin, /assets, /bbforce_cmd, /copyright, /dosignin, /dosignout,\r\n            /exec_cmd, /exec_pipe, /filer, /gui, /get_server_opt, /usesignout, /versions_cmdbox, /versions_used]\r\n    rule: allow\r\n  - groups: [readonly]\r\n    paths: [/gui/del_cmd, /gui/del_pipe, /gui/save_cmd, /gui/save_pipe]\r\n    rule: deny\r\n  - groups: [editor]\r\n    paths: [/gui/del_cmd, /gui/del_pipe, /gui/save_cmd, /gui/save_pipe]\r\n    rule: allow\r\noauth2:\r\n  providers:\r\n    google:\r\n      enabled: false\r\n      client_id: XXXXXXXXXXX\r\n      client_secret: XXXXXXXXXXX\r\n      redirect_uri: https://localhost:8443/oauth2/google/callback\r\n      scope: ['email']\r\n      note:\r\n      - https://developers.google.com/identity/protocols/oauth2/web-server?hl=ja#httprest\r\n    github:\r\n      enabled: false\r\n      client_id: XXXXXXXXXXX\r\n      client_secret: XXXXXXXXXXX\r\n      redirect_uri: https://localhost:8443/oauth2/github/callback\r\n      scope: ['user:email']\r\n      note:\r\n      - https://docs.github.com/ja/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#scopes\r\n```\r\n\r\n- See the documentation for references to each file.\r\n- Documentation is [here](https://hamacom2004jp.github.io/cmdbox/).\r\n\r\n\r\n# Lisence\r\n\r\nThis project is licensed under the MIT License, see the LICENSE file for details\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "cmdbox: It is a command line application with a plugin mechanism.",
    "version": "0.2.7.3",
    "project_urls": {
        "Download": "https://github.com/hamacom2004jp/cmdbox",
        "Homepage": "https://github.com/hamacom2004jp/cmdbox"
    },
    "split_keywords": [
        "cli",
        "restapi",
        "redis",
        "fastapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5b3023f72d31a469a073221f98548ca8d23bfcbcb2a7a277b748bbb0ddc2ec4a",
                "md5": "22c38f7c8390a3d7eafb7c49b7e2e138",
                "sha256": "c073e0d73949270d32c7525638f8624ec250ae322454172ebb7a8ea16678568c"
            },
            "downloads": -1,
            "filename": "cmdbox-0.2.7.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "22c38f7c8390a3d7eafb7c49b7e2e138",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 1709890,
            "upload_time": "2025-01-11T14:05:17",
            "upload_time_iso_8601": "2025-01-11T14:05:17.424001Z",
            "url": "https://files.pythonhosted.org/packages/5b/30/23f72d31a469a073221f98548ca8d23bfcbcb2a7a277b748bbb0ddc2ec4a/cmdbox-0.2.7.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "94e3832c3222da122d6d6c148c8d3be0068bf92ca636fbe4764c7c1f4fc2cb05",
                "md5": "5ca54091351b06005e022d8875f9b659",
                "sha256": "0d333e8c18ddc9abdc821361c7e1364bfd24fd38c1146604975d29084709e1c5"
            },
            "downloads": -1,
            "filename": "cmdbox-0.2.7.3.tar.gz",
            "has_sig": false,
            "md5_digest": "5ca54091351b06005e022d8875f9b659",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 1552487,
            "upload_time": "2025-01-11T14:05:19",
            "upload_time_iso_8601": "2025-01-11T14:05:19.666066Z",
            "url": "https://files.pythonhosted.org/packages/94/e3/832c3222da122d6d6c148c8d3be0068bf92ca636fbe4764c7c1f4fc2cb05/cmdbox-0.2.7.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-11 14:05:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "hamacom2004jp",
    "github_project": "cmdbox",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "argcomplete",
            "specs": []
        },
        {
            "name": "collectlicense",
            "specs": []
        },
        {
            "name": "cryptography",
            "specs": []
        },
        {
            "name": "fastapi",
            "specs": []
        },
        {
            "name": "gevent",
            "specs": []
        },
        {
            "name": "itsdangerous",
            "specs": []
        },
        {
            "name": "numpy",
            "specs": []
        },
        {
            "name": "Pillow",
            "specs": []
        },
        {
            "name": "python-multipart",
            "specs": []
        },
        {
            "name": "redis",
            "specs": []
        },
        {
            "name": "requests",
            "specs": []
        },
        {
            "name": "six",
            "specs": []
        },
        {
            "name": "sphinx",
            "specs": []
        },
        {
            "name": "sphinx-rtd-theme",
            "specs": []
        },
        {
            "name": "sphinx_fontawesome",
            "specs": []
        },
        {
            "name": "sphinx-intl",
            "specs": []
        },
        {
            "name": "sphinx-sitemap",
            "specs": []
        },
        {
            "name": "tabulate",
            "specs": []
        },
        {
            "name": "twine",
            "specs": []
        },
        {
            "name": "uvicorn",
            "specs": []
        },
        {
            "name": "wheel",
            "specs": []
        }
    ],
    "lcname": "cmdbox"
}
        
Elapsed time: 0.42862s