mycgi


Namemycgi JSON
Version 0.0.7 PyPI version JSON
download
home_pageNone
SummaryA Python3 replacement for the deprecated cgi module
upload_time2025-02-28 21:11:39
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseApache-2.0
keywords cgi replacement
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # mycgi - A Python3 Replacement for the Deprecated `cgi` Module

Other than using different class names (`mycgi.Form` instead of `cgi.FieldStorage` and `mycgi.Field` instead of `cgi.FieldStorage`) this module should be quite backward-compatible with the `mycgi` module. Additionally, JSON-encoded PUT and POST requests are supported.

Note that this module depends on the `python-multipart` package for handling POST and PUT requests that are not JSON-encoded.

## Some Usage Examples

```
# Instead of:
#from cgi import FieldStorage
# Use:
from mycgi import Form

form = Form()

# name is a text input field:
name = form.getvalue('name') # this will be a list if the form has multiple 'name' fields
# or: name = form.getfirst('name')
# or: names = form.getlist('name')

# spreadsheet is a file input field:
fileitem = form['spreadsheet']
# The name of the uploaded file:
filename = fileitem.filename
# Get the file contents as bytes 3 different ways:
contents = fileitem.file.read()
contents = fileitem.value
contents = form.getvalue('spreadsheet')
```

## Documentation

The initializer for the `mycgi.Form` class is:

```
    def __init__(self, environ=os.environ, fp=None, keep_blank_values=False):
        """
        Initialize a Form instance.

        Arguments (all are optional):

        environ: environment dictionary
                 default: os.environ

        fp: stream containing encoded POST and PUT data
            default: None (in which case sys.stdin.buffer will be used for
                     POST and PUT requests)

        keep_blank_values: flag indicating whether blank values in
                           percent-encoded forms should be treated as blank
                           strings.
                           default: False
        """

```

A `mycgi.Form` instance is a specialized dictionary whose keys are the field names and whose values are either a `mycgi.Field`
instance or a list of these instances. A `mycgi.Field` instance has the following attributes:

1. `name`:     The form field name.
2. `filename`: If this field is for a file, then the file's filename, else None.
3. `value`:    The form field value (or a file's contents as bytes).
4. `file`:     If this field is for a file, then a stream that can be read to get the uploaded file's value, else None.

The `mycgi.Form` class supports the `getvalue`, `getlist` and `getfirst` methods that behave identically to the like-named methods of the deprecated `cgi.FieldStorage` class and which make it unnecessary to access the `mycgi.Field` instances, although doing so can be useful for processing file uploads.

### JSON-encoded PUT and POST requests

Also supported are POST and PUT requests where the data is a JSON-encoded dictionary.

### WSGI Application Usage

To use `mycgi.Form` with a WSGI application:

```
from mycgi import Form

def wsgiApp(environ, start_response):
    form = Form(environ=environ, fp=environ['wsgi.input'])
    ...
```

## Tests To Demonstrate `mycgi` Usage

```
from mycgi import Form
import io

# Test a GET request:
form = Form(environ={'QUERY_STRING': 'x=1&x=2&y=3'})
assert repr(form) == "{'x': [Field('x', None, '1'), Field('x', None, '2')], 'y': Field('y', None, '3')}"

assert form.getvalue('x') == ['1', '2']
assert form.getlist('x') == ['1', '2']
assert form.getfirst('x') == '1'
assert [field.filename for field in form['x']] == [None, None]
assert [field.value for field in form['x']] == ['1', '2']

assert form.getvalue('y') == '3'
assert form.getlist('y') == ['3']
assert form.getfirst('y') == '3'
assert form['y'].name == 'y'
assert form['y'].filename is None
assert form['y'].value == '3'

# Test a multipart POST request:
# We have here a text input field named 'act' whose value is 'abc' and two
# file input fields named 'the_file' where a file has been selected for only the
# first occurence:
fp = io.BytesIO(b'------WebKitFormBoundarytQ0DkMXsDqxwxBlp\r\nContent-Disposition: form-data; name="act"\r\n\r\nTest\r\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp\r\nContent-Disposition: form-data; name="the_file"; filename="test.txt"\r\nContent-Type: text/plain\r\n\r\nabc\r\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp\r\nContent-Disposition: form-data; name="the_file"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp--\r\n')
environ = {
    'CONTENT_LENGTH': '431',
    'CONTENT_TYPE': 'multipart/form-data; boundary=----WebKitFormBoundarytQ0DkMXsDqxwxBlp',
    }
form = Form(environ=environ, fp=fp)

assert form['act'].name == 'act'
assert form['act'].filename is None
assert form['act'].value == 'Test'

assert form['the_file'][0].name == 'the_file'
assert form['the_file'][0].filename == 'test.txt'
assert form['the_file'][0].value == b'abc'

assert form['the_file'][1].name == 'the_file'
assert form['the_file'][1].filename == ''
assert form['the_file'][1].value == b''

assert form.getvalue('the_file') == [b'abc', b'']

# Test a JSON-encoded POST request:
fp = io.BytesIO(b'{"x": [1,2], "y": 3}')
environ = {
    'CONTENT_LENGTH': '20',
    'CONTENT_TYPE': 'application/json',
    }
form = Form(environ=environ, fp=fp)

assert form.getvalue('x') == [1, 2]
assert form.getlist('x') == [1, 2]
assert form.getfirst('x') == 1
assert [field.filename for field in form['x']] == [None, None]
assert [field.value for field in form['x']] == [1, 2]
assert [field.file for field in form['x']] == [None, None]

assert form.getvalue('y') == 3
assert form.getlist('y') == [3]
assert form.getfirst('y') == 3
assert form['y'].name == 'y'
assert form['y'].filename is None
assert form['y'].value == 3
assert form['y'].file is None
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "mycgi",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "cgi, replacement",
    "author": null,
    "author_email": "Ronald Aaronson <ronaldaaronson@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/34/8b/2afaecec525c49dac8a43d1bc635f42523f2b2b05f725e54c064fb68e76c/mycgi-0.0.7.tar.gz",
    "platform": null,
    "description": "# mycgi - A Python3 Replacement for the Deprecated `cgi` Module\r\n\r\nOther than using different class names (`mycgi.Form` instead of `cgi.FieldStorage` and `mycgi.Field` instead of `cgi.FieldStorage`) this module should be quite backward-compatible with the `mycgi` module. Additionally, JSON-encoded PUT and POST requests are supported.\r\n\r\nNote that this module depends on the `python-multipart` package for handling POST and PUT requests that are not JSON-encoded.\r\n\r\n## Some Usage Examples\r\n\r\n```\r\n# Instead of:\r\n#from cgi import FieldStorage\r\n# Use:\r\nfrom mycgi import Form\r\n\r\nform = Form()\r\n\r\n# name is a text input field:\r\nname = form.getvalue('name') # this will be a list if the form has multiple 'name' fields\r\n# or: name = form.getfirst('name')\r\n# or: names = form.getlist('name')\r\n\r\n# spreadsheet is a file input field:\r\nfileitem = form['spreadsheet']\r\n# The name of the uploaded file:\r\nfilename = fileitem.filename\r\n# Get the file contents as bytes 3 different ways:\r\ncontents = fileitem.file.read()\r\ncontents = fileitem.value\r\ncontents = form.getvalue('spreadsheet')\r\n```\r\n\r\n## Documentation\r\n\r\nThe initializer for the `mycgi.Form` class is:\r\n\r\n```\r\n    def __init__(self, environ=os.environ, fp=None, keep_blank_values=False):\r\n        \"\"\"\r\n        Initialize a Form instance.\r\n\r\n        Arguments (all are optional):\r\n\r\n        environ: environment dictionary\r\n                 default: os.environ\r\n\r\n        fp: stream containing encoded POST and PUT data\r\n            default: None (in which case sys.stdin.buffer will be used for\r\n                     POST and PUT requests)\r\n\r\n        keep_blank_values: flag indicating whether blank values in\r\n                           percent-encoded forms should be treated as blank\r\n                           strings.\r\n                           default: False\r\n        \"\"\"\r\n\r\n```\r\n\r\nA `mycgi.Form` instance is a specialized dictionary whose keys are the field names and whose values are either a `mycgi.Field`\r\ninstance or a list of these instances. A `mycgi.Field` instance has the following attributes:\r\n\r\n1. `name`:     The form field name.\r\n2. `filename`: If this field is for a file, then the file's filename, else None.\r\n3. `value`:    The form field value (or a file's contents as bytes).\r\n4. `file`:     If this field is for a file, then a stream that can be read to get the uploaded file's value, else None.\r\n\r\nThe `mycgi.Form` class supports the `getvalue`, `getlist` and `getfirst` methods that behave identically to the like-named methods of the deprecated `cgi.FieldStorage` class and which make it unnecessary to access the `mycgi.Field` instances, although doing so can be useful for processing file uploads.\r\n\r\n### JSON-encoded PUT and POST requests\r\n\r\nAlso supported are POST and PUT requests where the data is a JSON-encoded dictionary.\r\n\r\n### WSGI Application Usage\r\n\r\nTo use `mycgi.Form` with a WSGI application:\r\n\r\n```\r\nfrom mycgi import Form\r\n\r\ndef wsgiApp(environ, start_response):\r\n    form = Form(environ=environ, fp=environ['wsgi.input'])\r\n    ...\r\n```\r\n\r\n## Tests To Demonstrate `mycgi` Usage\r\n\r\n```\r\nfrom mycgi import Form\r\nimport io\r\n\r\n# Test a GET request:\r\nform = Form(environ={'QUERY_STRING': 'x=1&x=2&y=3'})\r\nassert repr(form) == \"{'x': [Field('x', None, '1'), Field('x', None, '2')], 'y': Field('y', None, '3')}\"\r\n\r\nassert form.getvalue('x') == ['1', '2']\r\nassert form.getlist('x') == ['1', '2']\r\nassert form.getfirst('x') == '1'\r\nassert [field.filename for field in form['x']] == [None, None]\r\nassert [field.value for field in form['x']] == ['1', '2']\r\n\r\nassert form.getvalue('y') == '3'\r\nassert form.getlist('y') == ['3']\r\nassert form.getfirst('y') == '3'\r\nassert form['y'].name == 'y'\r\nassert form['y'].filename is None\r\nassert form['y'].value == '3'\r\n\r\n# Test a multipart POST request:\r\n# We have here a text input field named 'act' whose value is 'abc' and two\r\n# file input fields named 'the_file' where a file has been selected for only the\r\n# first occurence:\r\nfp = io.BytesIO(b'------WebKitFormBoundarytQ0DkMXsDqxwxBlp\\r\\nContent-Disposition: form-data; name=\"act\"\\r\\n\\r\\nTest\\r\\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp\\r\\nContent-Disposition: form-data; name=\"the_file\"; filename=\"test.txt\"\\r\\nContent-Type: text/plain\\r\\n\\r\\nabc\\r\\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp\\r\\nContent-Disposition: form-data; name=\"the_file\"; filename=\"\"\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n\\r\\n------WebKitFormBoundarytQ0DkMXsDqxwxBlp--\\r\\n')\r\nenviron = {\r\n    'CONTENT_LENGTH': '431',\r\n    'CONTENT_TYPE': 'multipart/form-data; boundary=----WebKitFormBoundarytQ0DkMXsDqxwxBlp',\r\n    }\r\nform = Form(environ=environ, fp=fp)\r\n\r\nassert form['act'].name == 'act'\r\nassert form['act'].filename is None\r\nassert form['act'].value == 'Test'\r\n\r\nassert form['the_file'][0].name == 'the_file'\r\nassert form['the_file'][0].filename == 'test.txt'\r\nassert form['the_file'][0].value == b'abc'\r\n\r\nassert form['the_file'][1].name == 'the_file'\r\nassert form['the_file'][1].filename == ''\r\nassert form['the_file'][1].value == b''\r\n\r\nassert form.getvalue('the_file') == [b'abc', b'']\r\n\r\n# Test a JSON-encoded POST request:\r\nfp = io.BytesIO(b'{\"x\": [1,2], \"y\": 3}')\r\nenviron = {\r\n    'CONTENT_LENGTH': '20',\r\n    'CONTENT_TYPE': 'application/json',\r\n    }\r\nform = Form(environ=environ, fp=fp)\r\n\r\nassert form.getvalue('x') == [1, 2]\r\nassert form.getlist('x') == [1, 2]\r\nassert form.getfirst('x') == 1\r\nassert [field.filename for field in form['x']] == [None, None]\r\nassert [field.value for field in form['x']] == [1, 2]\r\nassert [field.file for field in form['x']] == [None, None]\r\n\r\nassert form.getvalue('y') == 3\r\nassert form.getlist('y') == [3]\r\nassert form.getfirst('y') == 3\r\nassert form['y'].name == 'y'\r\nassert form['y'].filename is None\r\nassert form['y'].value == 3\r\nassert form['y'].file is None\r\n```\r\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A Python3 replacement for the deprecated cgi module",
    "version": "0.0.7",
    "project_urls": {
        "Changelog": "https://github.com/ronaaronson/mycgi/tags",
        "Homepage": "https://github.com/ronaaronson/mycgi",
        "Source": "https://github.com/ronaaronson/mycgi"
    },
    "split_keywords": [
        "cgi",
        " replacement"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6d9148fc624e60f71015bcaba40e58361169151c7dfcac32e662b7c997e22104",
                "md5": "d78735537287708f73971ce0e7223177",
                "sha256": "d3ad9a1b1a77120298ef8b152d388797870d146c754cff5df9725e68b22127d3"
            },
            "downloads": -1,
            "filename": "mycgi-0.0.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d78735537287708f73971ce0e7223177",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 5610,
            "upload_time": "2025-02-28T21:11:37",
            "upload_time_iso_8601": "2025-02-28T21:11:37.973416Z",
            "url": "https://files.pythonhosted.org/packages/6d/91/48fc624e60f71015bcaba40e58361169151c7dfcac32e662b7c997e22104/mycgi-0.0.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "348b2afaecec525c49dac8a43d1bc635f42523f2b2b05f725e54c064fb68e76c",
                "md5": "a77d5eb354cfe5fd6276c884669eff13",
                "sha256": "4e3ab96f6e18dab6ddce55845c221e835a9b1b7bd312b139035f16c6a27bbfa7"
            },
            "downloads": -1,
            "filename": "mycgi-0.0.7.tar.gz",
            "has_sig": false,
            "md5_digest": "a77d5eb354cfe5fd6276c884669eff13",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 5634,
            "upload_time": "2025-02-28T21:11:39",
            "upload_time_iso_8601": "2025-02-28T21:11:39.623686Z",
            "url": "https://files.pythonhosted.org/packages/34/8b/2afaecec525c49dac8a43d1bc635f42523f2b2b05f725e54c064fb68e76c/mycgi-0.0.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-28 21:11:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ronaaronson",
    "github_project": "mycgi",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "mycgi"
}
        
Elapsed time: 1.55831s