{ "info": { "author": "Thibault B\u00e9tr\u00e9mieux", "author_email": "thibault.betremieux@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: Public Domain", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "[![CircleCI](https://circleci.com/gh/ThibTrip/dash_database.svg?style=svg)](https://circleci.com/gh/ThibTrip/dash_database) [![codecov](https://codecov.io/gh/ThibTrip/dash_database/branch/master/graph/badge.svg)](https://codecov.io/gh/ThibTrip/dash_database)\n\n# dash_database\n\nManages user values for a [dash](https://github.com/plotly/dash) app. This is an alternative solution for [sharing data between callbacks](https://dash.plot.ly/sharing-data-between-callbacks) based on the library sqlitedict. \n\nIt has the following benefits:\n\n* easy installation via git clone and pip install (I would like to push dash_database to PyPI to make it even easier but want to make sure there aren't any issues inherent to using sqlitedict first) unlike redis\n* no need to fiddle with json dumps and pickles unlike redis or dcc.Store. It takes any picklable objects out of the box.\n* no need to have a redis server running\n* it is thread safe\n* it can work in memory\n\n# Installation\n\n```\n# clone repository\ngit clone https://github.com/ThibTrip/dash_database.git\n# install dash_database\npip install ./dash_database # do not forget ./ (from local folder and not from Python Package Index)\n```\n\n# Usage\n\n## Basic usage\n\nImport the main object DashDatabase and you can start managing data already. Detailled information on the arguments of DashDatabase's methods and how the class was implemented can be found in its docstring.\n\n```python\nfrom dash_database import DashDatabase\n\n# create an instance of DashDatabase\ndash_db = DashDatabase(db_location = None) # if None it is created in a temp folder and deleted after use\n\n# save values for user 123\ndash_db.store_user_value(user_id = 123, key_name = 'account_id', value = 46887)\ndash_db.store_user_value(user_id = 123, key_name = 'favorite_animal', value = 'monkey')\ndash_db.list_stored_user_keys(123) # list the names of the keys used by the user\n['account_id', 'favorite_animal']\n\n# save values for user 456\ndash_db.store_user_value(user_id = 456, key_name = 'account_id', value = 87874)\ndash_db.store_user_value(456, 'favorite_color', 'green')\ndash_db.list_stored_user_keys(456) # list the names of the keys used by the user\n['account_id', 'favorite_color']\n\n# get the value behind a user key\ndash_db.get_user_value(user_id = 123, key_name = 'favorite_animal')\n'monkey'\n\n# delete a key and its value for a user\ndash_db.delete_user_value(user_id = 123, key_name = 'favorite_animal', \n # when if_not_exists is equal to \"raise\" you get an error if a key does not exist\n # if it is equal to \"ignore\" nothing happens if it does not exist (default)\n if_not_exists = 'ignore') \n\n# delete all keys and their values for a user\ndash_db.delete_all_user_values(456)\n\n# list all keys of the users again for testing purposes\ndash_db.list_stored_user_keys(123)\n['account_id']\ndash_db.list_stored_user_keys(456)\n[]\n```\n\n## Example with a dash app\n\n```python\nimport dash\nimport dash_core_components as dcc\nimport dash_html_components as html\nfrom dash.dependencies import Input, Output, State\nfrom dash.exceptions import PreventUpdate\nfrom dash_database import DashDatabase\nimport uuid\n\ndef serve_layout():\n \"\"\"Creates the layout for each user of the app.\n This function is executed each time a session is created for the app.\n It creates a new session id (a uuid.uuid1 as string) each time.\n\n This session id will be used in combination with a DashDatabase instance to manage user values.\n It will be fetched via the property data of a dcc.Store component.\n \"\"\"\n \n # create a session id\n session_id = str(uuid.uuid1())\n \n # store the session id in a dcc.Store component (invisible component for storing data)\n store_session_id_div = dcc.Store(id='session_id_div_id', \n storage_type = 'session', # IMPORTANT! see docstring of dcc.Store \n data = session_id)\n \n # create tab to enter a value\n first_tab = dcc.Tab(label = \"Enter a value\", \n children = [dcc.Input(placeholder = \"Enter value here\", id = \"input_div\"),\n html.Button(children = \"OK\", id = \"ok_button\"),\n dcc.Markdown(id = \"success_value_saved\")])\n \n # create tab to retrieve the value entered in the other tab\n second_tab = dcc.Tab(label = \"Retrieve the value\",\n children = [html.Button(children = \"Show me the value\", id = \"show_value_button\"),\n dcc.Markdown(id = \"show_value_div\")])\n \n # assemble tabs in dcc.Tabs object\n tabs = dcc.Tabs(children = [first_tab, second_tab])\n\n \n # create layout\n layout = html.Div(children = [tabs, store_session_id_div])\n\n \n return layout\n\n\n# putting your callbacks in functions is a nice trick to be able to move them in other modules and import them \ndef create_callback_save_value(app:dash.Dash, \n dash_db:DashDatabase):\n @app.callback(Output('success_value_saved', 'children'),\n [Input('ok_button', 'n_clicks')], # the button triggers the callback\n [State('input_div', 'value'), # additional info that does not trigger the callback \n State('session_id_div_id', 'data')]) # used to identify the user and save its data\n def save_value(n_clicks, value, session_id):\n \n # when the app starts all callbacks are triggered by default. \n # raise a PreventUpdate to avoid the callback trigger at start (n_clicks is None at this point)\n if n_clicks is None:\n raise PreventUpdate\n \n # save value \n dash_db.store_user_value(user_id = session_id, \n key_name = 'value', \n value = value)\n \n # return success message\n return \"Your value was sucessfully saved. Try to retrieve it in the other tab now :)!\"\n \ndef create_callback_retrieve_value(app:dash.Dash, \n dash_db:DashDatabase):\n @app.callback(Output('show_value_div', 'children'),\n [Input('show_value_button', 'n_clicks')],\n [State('session_id_div_id', 'data')])\n def retrieve_value(n_clicks, session_id):\n \n # when the app starts all callbacks are triggered by default. \n # raise a PreventUpdate to avoid the callback trigger at start (n_clicks is 0 at this point)\n if n_clicks is None:\n raise PreventUpdate\n \n # save value \n value = dash_db.get_user_value(user_id = session_id, \n key_name = 'value')\n \n # return success message\n return f\"Your value is {value}\"\n \n \n# create the app, add the layout and the callbacks\napp = dash.Dash()\napp.layout = serve_layout\ndash_db = DashDatabase() # create a DashDatabase instance for managing user values\ncreate_callback_save_value(app, dash_db)\ncreate_callback_retrieve_value(app, dash_db)\n\nif __name__ == \"__main__\":\n app.run_server(debug = True) # set to False if running in a Jupyter Notebook or in Jupyter Lab!\n \n```", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/ThibTrip/dash_database/archive/v1.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ThibTrip/dash_database", "keywords": "dash,plotly", "license": "The Unlicense", "maintainer": "", "maintainer_email": "", "name": "dash-database", "package_url": "https://pypi.org/project/dash-database/", "platform": "", "project_url": "https://pypi.org/project/dash-database/", "project_urls": { "Download": "https://github.com/ThibTrip/dash_database/archive/v1.tar.gz", "Homepage": "https://github.com/ThibTrip/dash_database" }, "release_url": "https://pypi.org/project/dash-database/1.0/", "requires_dist": null, "requires_python": "", "summary": "Manages user values for a dash app.", "version": "1.0" }, "last_serial": 5799473, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "3fdf03a8b646c037e0b63dcb9076edb7", "sha256": "311a19e196f7edb16cc5def9d4593005dc092a83736ff8adfa1aab82a0fac0a3" }, "downloads": -1, "filename": "dash_database-1.0.tar.gz", "has_sig": false, "md5_digest": "3fdf03a8b646c037e0b63dcb9076edb7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6497, "upload_time": "2019-09-08T14:36:25", "url": "https://files.pythonhosted.org/packages/eb/f5/bb2165c82256ee7d009d978bea4097f4268407e57b8880b5f776036e1c4b/dash_database-1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3fdf03a8b646c037e0b63dcb9076edb7", "sha256": "311a19e196f7edb16cc5def9d4593005dc092a83736ff8adfa1aab82a0fac0a3" }, "downloads": -1, "filename": "dash_database-1.0.tar.gz", "has_sig": false, "md5_digest": "3fdf03a8b646c037e0b63dcb9076edb7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6497, "upload_time": "2019-09-08T14:36:25", "url": "https://files.pythonhosted.org/packages/eb/f5/bb2165c82256ee7d009d978bea4097f4268407e57b8880b5f776036e1c4b/dash_database-1.0.tar.gz" } ] }