questions


Namequestions JSON
Version 0.8.0 PyPI version JSON
download
home_pagehttps://github.com/cguardia/questions
SummaryQuestions is a form library that uses the power of SurveyJS for the UI.
upload_time2023-04-11 00:09:31
maintainer
docs_urlNone
authorCarlos de la Guardia
requires_python>=3.8
licenseMIT license
keywords questions
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            =========
Questions
=========


.. image:: https://img.shields.io/pypi/v/questions.svg
        :target: https://pypi.python.org/pypi/questions

.. image:: https://github.com/cguardia/questions/workflows/continuous-integration/badge.svg
        :target: https://github.com/cguardia/questions/actions?query=workflow%3Acontinuous-integration

.. image:: https://readthedocs.org/projects/questions/badge/?version=latest
        :target: https://questions.readthedocs.io/en/latest/?badge=latest
        :alt: Documentation Status




Questions is a Python form library that uses the power of SurveyJS_ for the UI.
The philosophy behind Questions is that modern form rendering usually requires
integrating some complex Javascript widgets anyway, so why not skip the markup
generation completely? 

.. image:: https://www.delaguardia.com.mx/questions.gif

In Questions, forms are defined in Python similarly to other form frameworks,
but everything on the front end is handled by SurveyJS. This provides a lot of
benefits:

* Nice, integrated UI, with powerful Javascript widgets.
* SurveyJS is compatible with Angular2, JQuery, KnockoutJS, React and VueJS.
  Questions makes sure that you get the right files for each version.
* More than 20 question types, from simple text inputs and dropdowns to
  elaborate widgets like dynamic panels and checkbox matrices.
* Multiple look and feel options (themes), including Bootstrap_ CSS support.
* Full client side validation (plus server side checking, too).
* Use simple text expressions in question declarations to control which
  questions to show depending on the answers to previous ones.
* Complex forms can be defined easily using class composition.
* Easy multi-page forms, with no state-keeping headaches.
* Create forms directly from JSON definitions using SurveyJS form creator.
* Generate Python code from dynamic JSON import.
* Minimal code for simple apps. If you just need a form or two, you are set.
* Zero Javascript code option. If you can use a CDN, no need to install or
  download any javascript.
* Out of the box integration with popular third party widgets, like select2_
  and ckeditor_.
* Supports the creation of tests and quizzes, by defining "correct" answers to
  the questions, and optionally setting a maximum time to finish.

.. _SurveyJS: https://surveyjs.io
.. _Bootstrap: https://getbootstrap.com
.. _select2: https://select2.org/
.. _ckeditor: https://ckeditor.com/ckeditor-4/


How the Code Looks
------------------

To get a feel for how Questions works, nothing better than looking at a simple
example::

    from questions import Form
    from questions import TextQuestion
    from questions import RadioGroupQuestion


    class SimpleForm(Form):
        name = TextQuestion()
        email = TextQuestion(input_type="email", required="True")
        favorite_number = TextQuestion(title="What is your favorite number?",
            input_type="number")
        language = RadioGroupQuestion(title="Favorite Language",
            choices=["Python", "Other"])
        version = RadioGroupQuestion(title="Preferred Python Version",
            choices=["Python 2", "Python 3"],
            visible_if="{language} = 'Python'")

This is a fairly conventional way to define forms, so no surprises here, but
look at the way the ``input_type`` parameter allows us to use different HTML5
text input methods. Pay special attention to the last line, where we use the
``visible_if`` parameter to only show the Python version question if the
answer to the ``language`` question is "Python". Defining "live" form behavior
in this way is something that is usually out of scope for server side code,
but Questions' SurveyJS integration allows us to do it.


Full Working Multi-page Flask Application
-----------------------------------------

Let's show how easy things can be if your applications needs are simple. The
following is a complete application using the popular Flask_ web framework::

    from flask import Flask
    from flask import redirect
    from flask import request

    from questions import Form
    from questions import FormPage
    from questions import TextQuestion
    from questions import DropdownQuestion


    class PageOne(Form):
        name = TextQuestion()
        email = TextQuestion(input_type="email", required="True")


    class PageTwo(Form):
        country = DropdownQuestion(choices_by_url={"value_name": "name",
            "url": "https://restcountries.eu/rest/v2/all"})
        birthdate = TextQuestion(input_type="date")


    class Profile(Form):
        page_one = FormPage(PageOne, title="Identification Information")
        page_two = FormPage(PageTwo, title="Additional Information")


    app = Flask(__name__)

    @app.route("/", methods=("GET",))
    def form():
        form = Profile()
        return form.render_html()

    @app.route("/", methods=("POST",))
    def post():
        form_data = request.get_json()
        # Here, we would save to a database or something
        print(form_data)
        return redirect("/thanks")

    @app.route("/thanks")
    def thanks():
        return "Thanks for your information"

    if __name__ == "__main__":
        app.run()

By default, Questions uses a CDN for fetching the Javascript resources, which
is why all that is needed to run the above code is installing Flask and
Questions. Of course, it is possible to install all the dependencies yourself
and configure Questions to use your installation, but sometimes this is all
that's required to get a full working application.

Admittedly, our application doesn't do much, but we get a working form that you
can fill and submit in your browser. See how easy it is to get a multi-page
form with navigation buttons. Also, notice how ``get_json`` is the only Flask
request call we need to get the form data. 

As the code shows, defining a multiple page form is very simple, and allows us
to keep the form pages logically separated, and even using them independently
or in combination with other forms with little additional work.

Finally, take a look at the ``choices_by_url`` parameter in the
DropdownQuestion, which allows us to get the dropdown choices from separate,
restful web services.

.. _Flask: https://flask.palletsprojects.com/


License and Documentation
-------------------------

* Free software: MIT license
* Documentation: https://questions.readthedocs.io.


Credits
-------

This package was created with Cookiecutter_ and the
`audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage


=======
History
=======

0.5.0a0 (2020-10-01)
--------------------

* First release on PyPI.

0.5.0a1 (2020-12-09)
--------------------

* Fix bug that caused Questions to crash when two or more panels were used in
  one form.

* Add feature for creating Form subclasses from JSON data.

* Add screencast to README page.

* Update docs.

* Update dependencies to latest versions.

0.5.0a2 (2020-12-09)
--------------------

* Fix bug with form parameters in from_json conversion.

0.5.0a3 (2020-12-10)
--------------------

* Make sure jinja templates are included in manifest.

0.7.0a4 (2020-12-13)
--------------------

* Update installation docs to mention typing-extensions requirement for
  Python < 3.8.

* Use correct default value for allow_clear in signature pad.

* Set type hints to allow localization arrays in visible text properties.

* Fix bug when generating classes from JSON with dynamic panels.

* Add string representation methods to main classes.

* Feature: add console script for generating code for classes created with
  from_json method.

0.7.1 (2022-09-18)
------------------

* Bug fix: do not add a default page when other pages are defined.
* Update js CDN and tests.

0.8.0 (2023-04-10)
------------------

* Bug fix: fix choices with translatable text (thanks @joan-qida).
* Bug fix: fix read the docs build.
* Update SurveyJS version.
* Use current SurveyJS supported themes.
* Include newer Python versions in tests.
* Add documentation for i18n.
* Various dependency updates.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/cguardia/questions",
    "name": "questions",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "questions",
    "author": "Carlos de la Guardia",
    "author_email": "cguardia@yahoo.com",
    "download_url": "https://files.pythonhosted.org/packages/35/b0/cf10e034bb8815434e28c947f24297ff08b888b9585a1d8c6f8ae09831e4/questions-0.8.0.tar.gz",
    "platform": null,
    "description": "=========\nQuestions\n=========\n\n\n.. image:: https://img.shields.io/pypi/v/questions.svg\n        :target: https://pypi.python.org/pypi/questions\n\n.. image:: https://github.com/cguardia/questions/workflows/continuous-integration/badge.svg\n        :target: https://github.com/cguardia/questions/actions?query=workflow%3Acontinuous-integration\n\n.. image:: https://readthedocs.org/projects/questions/badge/?version=latest\n        :target: https://questions.readthedocs.io/en/latest/?badge=latest\n        :alt: Documentation Status\n\n\n\n\nQuestions is a Python form library that uses the power of SurveyJS_ for the UI.\nThe philosophy behind Questions is that modern form rendering usually requires\nintegrating some complex Javascript widgets anyway, so why not skip the markup\ngeneration completely? \n\n.. image:: https://www.delaguardia.com.mx/questions.gif\n\nIn Questions, forms are defined in Python similarly to other form frameworks,\nbut everything on the front end is handled by SurveyJS. This provides a lot of\nbenefits:\n\n* Nice, integrated UI, with powerful Javascript widgets.\n* SurveyJS is compatible with Angular2, JQuery, KnockoutJS, React and VueJS.\n  Questions makes sure that you get the right files for each version.\n* More than 20 question types, from simple text inputs and dropdowns to\n  elaborate widgets like dynamic panels and checkbox matrices.\n* Multiple look and feel options (themes), including Bootstrap_ CSS support.\n* Full client side validation (plus server side checking, too).\n* Use simple text expressions in question declarations to control which\n  questions to show depending on the answers to previous ones.\n* Complex forms can be defined easily using class composition.\n* Easy multi-page forms, with no state-keeping headaches.\n* Create forms directly from JSON definitions using SurveyJS form creator.\n* Generate Python code from dynamic JSON import.\n* Minimal code for simple apps. If you just need a form or two, you are set.\n* Zero Javascript code option. If you can use a CDN, no need to install or\n  download any javascript.\n* Out of the box integration with popular third party widgets, like select2_\n  and ckeditor_.\n* Supports the creation of tests and quizzes, by defining \"correct\" answers to\n  the questions, and optionally setting a maximum time to finish.\n\n.. _SurveyJS: https://surveyjs.io\n.. _Bootstrap: https://getbootstrap.com\n.. _select2: https://select2.org/\n.. _ckeditor: https://ckeditor.com/ckeditor-4/\n\n\nHow the Code Looks\n------------------\n\nTo get a feel for how Questions works, nothing better than looking at a simple\nexample::\n\n    from questions import Form\n    from questions import TextQuestion\n    from questions import RadioGroupQuestion\n\n\n    class SimpleForm(Form):\n        name = TextQuestion()\n        email = TextQuestion(input_type=\"email\", required=\"True\")\n        favorite_number = TextQuestion(title=\"What is your favorite number?\",\n            input_type=\"number\")\n        language = RadioGroupQuestion(title=\"Favorite Language\",\n            choices=[\"Python\", \"Other\"])\n        version = RadioGroupQuestion(title=\"Preferred Python Version\",\n            choices=[\"Python 2\", \"Python 3\"],\n            visible_if=\"{language} = 'Python'\")\n\nThis is a fairly conventional way to define forms, so no surprises here, but\nlook at the way the ``input_type`` parameter allows us to use different HTML5\ntext input methods. Pay special attention to the last line, where we use the\n``visible_if`` parameter to only show the Python version question if the\nanswer to the ``language`` question is \"Python\". Defining \"live\" form behavior\nin this way is something that is usually out of scope for server side code,\nbut Questions' SurveyJS integration allows us to do it.\n\n\nFull Working Multi-page Flask Application\n-----------------------------------------\n\nLet's show how easy things can be if your applications needs are simple. The\nfollowing is a complete application using the popular Flask_ web framework::\n\n    from flask import Flask\n    from flask import redirect\n    from flask import request\n\n    from questions import Form\n    from questions import FormPage\n    from questions import TextQuestion\n    from questions import DropdownQuestion\n\n\n    class PageOne(Form):\n        name = TextQuestion()\n        email = TextQuestion(input_type=\"email\", required=\"True\")\n\n\n    class PageTwo(Form):\n        country = DropdownQuestion(choices_by_url={\"value_name\": \"name\",\n            \"url\": \"https://restcountries.eu/rest/v2/all\"})\n        birthdate = TextQuestion(input_type=\"date\")\n\n\n    class Profile(Form):\n        page_one = FormPage(PageOne, title=\"Identification Information\")\n        page_two = FormPage(PageTwo, title=\"Additional Information\")\n\n\n    app = Flask(__name__)\n\n    @app.route(\"/\", methods=(\"GET\",))\n    def form():\n        form = Profile()\n        return form.render_html()\n\n    @app.route(\"/\", methods=(\"POST\",))\n    def post():\n        form_data = request.get_json()\n        # Here, we would save to a database or something\n        print(form_data)\n        return redirect(\"/thanks\")\n\n    @app.route(\"/thanks\")\n    def thanks():\n        return \"Thanks for your information\"\n\n    if __name__ == \"__main__\":\n        app.run()\n\nBy default, Questions uses a CDN for fetching the Javascript resources, which\nis why all that is needed to run the above code is installing Flask and\nQuestions. Of course, it is possible to install all the dependencies yourself\nand configure Questions to use your installation, but sometimes this is all\nthat's required to get a full working application.\n\nAdmittedly, our application doesn't do much, but we get a working form that you\ncan fill and submit in your browser. See how easy it is to get a multi-page\nform with navigation buttons. Also, notice how ``get_json`` is the only Flask\nrequest call we need to get the form data. \n\nAs the code shows, defining a multiple page form is very simple, and allows us\nto keep the form pages logically separated, and even using them independently\nor in combination with other forms with little additional work.\n\nFinally, take a look at the ``choices_by_url`` parameter in the\nDropdownQuestion, which allows us to get the dropdown choices from separate,\nrestful web services.\n\n.. _Flask: https://flask.palletsprojects.com/\n\n\nLicense and Documentation\n-------------------------\n\n* Free software: MIT license\n* Documentation: https://questions.readthedocs.io.\n\n\nCredits\n-------\n\nThis package was created with Cookiecutter_ and the\n`audreyr/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage\n\n\n=======\nHistory\n=======\n\n0.5.0a0 (2020-10-01)\n--------------------\n\n* First release on PyPI.\n\n0.5.0a1 (2020-12-09)\n--------------------\n\n* Fix bug that caused Questions to crash when two or more panels were used in\n  one form.\n\n* Add feature for creating Form subclasses from JSON data.\n\n* Add screencast to README page.\n\n* Update docs.\n\n* Update dependencies to latest versions.\n\n0.5.0a2 (2020-12-09)\n--------------------\n\n* Fix bug with form parameters in from_json conversion.\n\n0.5.0a3 (2020-12-10)\n--------------------\n\n* Make sure jinja templates are included in manifest.\n\n0.7.0a4 (2020-12-13)\n--------------------\n\n* Update installation docs to mention typing-extensions requirement for\n  Python < 3.8.\n\n* Use correct default value for allow_clear in signature pad.\n\n* Set type hints to allow localization arrays in visible text properties.\n\n* Fix bug when generating classes from JSON with dynamic panels.\n\n* Add string representation methods to main classes.\n\n* Feature: add console script for generating code for classes created with\n  from_json method.\n\n0.7.1 (2022-09-18)\n------------------\n\n* Bug fix: do not add a default page when other pages are defined.\n* Update js CDN and tests.\n\n0.8.0 (2023-04-10)\n------------------\n\n* Bug fix: fix choices with translatable text (thanks @joan-qida).\n* Bug fix: fix read the docs build.\n* Update SurveyJS version.\n* Use current SurveyJS supported themes.\n* Include newer Python versions in tests.\n* Add documentation for i18n.\n* Various dependency updates.\n",
    "bugtrack_url": null,
    "license": "MIT license",
    "summary": "Questions is a form library that uses the power of SurveyJS for the UI.",
    "version": "0.8.0",
    "split_keywords": [
        "questions"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "57e6684f41960cc23e08f8fd58f3b488c66cc9bf85c174b06f1b5c3547a8d164",
                "md5": "8fe398b8492c18a0433d1906f7d1f6e2",
                "sha256": "c726d8580c922760fb7d9a3587757de7e0ccee80bd4e75c1b82afe479d945ebe"
            },
            "downloads": -1,
            "filename": "questions-0.8.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8fe398b8492c18a0433d1906f7d1f6e2",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.8",
            "size": 32539,
            "upload_time": "2023-04-11T00:09:29",
            "upload_time_iso_8601": "2023-04-11T00:09:29.152135Z",
            "url": "https://files.pythonhosted.org/packages/57/e6/684f41960cc23e08f8fd58f3b488c66cc9bf85c174b06f1b5c3547a8d164/questions-0.8.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "35b0cf10e034bb8815434e28c947f24297ff08b888b9585a1d8c6f8ae09831e4",
                "md5": "bfb8c7499394d281fbae9ae712ca255f",
                "sha256": "3c81f4ad0baf8ad489ff1102bb9c10ae5fbe882788e8dfe6c3ca8dcb5f22de35"
            },
            "downloads": -1,
            "filename": "questions-0.8.0.tar.gz",
            "has_sig": false,
            "md5_digest": "bfb8c7499394d281fbae9ae712ca255f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 51636,
            "upload_time": "2023-04-11T00:09:31",
            "upload_time_iso_8601": "2023-04-11T00:09:31.690505Z",
            "url": "https://files.pythonhosted.org/packages/35/b0/cf10e034bb8815434e28c947f24297ff08b888b9585a1d8c6f8ae09831e4/questions-0.8.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-11 00:09:31",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "cguardia",
    "github_project": "questions",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "questions"
}
        
Elapsed time: 0.05348s