# ๐ Banana Manager
Welcome to **Banana Manager**! Banana Manager is a Python package designed to connect to a database and create a simple web app that displays and allows updates to selected tables. This tool is perfect for non-technical end-users who need to interact with database tables without using complex DBA tools.
## Powered by
- **[Dash](https://dash.plotly.com/) and [AG Grid](https://www.ag-grid.com/)**: User-friendly, intuitive, and interactive web interface with powerful table displays and editing capabilities.
- **[Pydantic](https://pydantic-docs.helpmanual.io/) and [YAML](https://yaml.org/)**: Fast and accurate data handling and configuration.
- **[SQLAlchemy](https://www.sqlalchemy.org/)**: Secure, efficient, and flexible database operations for multiple database backends.
## Installation
To install Banana Manager, simply use pip:
```bash
pip install banana-manager
```
Also, remember to install the appropriate database connector for your project, like `pyodbc` or `psycopg2`. If youโre unsure, SQLAlchemy will inform you when you load your application.
Additionally, consider installing a production server like `waitress`:
```bash
pip install waitress
```
## Getting started
At the end of this tutorial, youโll have a folder structure similar to the following:
```
my_manager
โโ app.py
โโ config.yaml
โโ my_tables
โโ my_group_of_tables.yaml
โโ another_group_of_tables.yaml
```
### Configuring the Manager
Create a `config.yaml` file in the root folder of your project with the following structure:
```yaml
connection:
drivername: <optional str>
username: <optional str>
password: <optional str>
host: <optional str>
port: <optional str>
database: <optional str>
dataPath: "data"
tablePaths: ["tables"]
title: "Banana Database Manager"
theme: <optional str>
defaultColDef: <optional dict>
defaultGridOptions: <optional dict>
```
- **connection** *(dict)* : This will create a [SQLAlchemy URL](https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.engine.URL) object. See the section [Dialets](https://docs.sqlalchemy.org/en/20/dialects/) for more information about the appropriate driver.
- **dataPath** *(str, default="data")* : The folder where the app data files will be stored.
- **tablePaths** *(list[str], default=["tables"])* : List of folder where the table models YAML files are stored.
- **title** *(str, default="Banana Database Manager")* : HTML header title attribute.
- **theme** *(str, default="cyan")* : One of the [default Mantine colors](https://mantine.dev/theming/colors/#default-colors).
- **defaultColDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).
- **defaultGridOptions** *(dict[str, Any])* : [AG Grid options](https://www.ag-grid.com/react-data-grid/grid-options/).
### Defining the tables
The tables can be defined using YAML files located in the folders specified in the `config.yaml`. If no folder is specified, create a new folder named "tables" in the root folder.
Each YAML file represents a group containing a list of tables. Hereโs the structure:
```yaml
groupName: <optional string>
displayOrder: <optional integer>
tables:
- name: <string>
schemaName: <optional string>
displayName: <optional string>
columns:
- name: <string>
displayName: <optional string>
dataType: (optional)
data: <optional dict>
type: <string>
columnDef: <optional dict>
- <other columns>
orderBy: (optional)
- column: <string>
desc: <optional bool>
- <other columns>
limit: <optional int>
defaultColDef: <optional dict>
gridOptions: <optional dict>
- <other tables>
```
#### Group configuration
- **groupName** *(str, optional)* : Name of the group that will be displayed in the side menu.
- **displayOrder** *(int, optional)* : Order which the groups will be stacked in the side menu.
- **tables** *(list)* : List of table configurations.
#### Table configuration
- **name** *(str)* : Name of the table in the database.
- **schemaName** *(str, optional)* : Schema where the table is located in the database.
- **displayName** : *(str, optional)* : Name that will be displayed at the side menu.
- **columns** *(list)* : List of column configurations.
- **orderBy** *(list[dict])* : Default ordering of the table rows.
- **limit** *(int)* : Maximum of rows returned after order by.
- **defaultColDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).
- **gridOptions** *(dict[str, Any])* : [AG Grid options](https://www.ag-grid.com/react-data-grid/grid-options/).
#### Order by configuration
- **column** *(str)* : Name of the column
- **desc** *(bool, optional)* : If True, order table by column in descending order.
#### Column configuration
- **name** *(str)* : Name of the column in the database.
- **displayName** *(str, optional)* : Name that will be displayed in the table.
- **dataType** *(dict, optional)* : Set the column to one of the special data types.
- **columnDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).
#### Data type configuration
The `dataType` argument customizes how column data is interpreted and displayed. It consists of two keys:
- **`type`** *(str)*: Specifies the data type. Available options are:
- **`default`**: Standard data type, no special handling.
- **`color`**: Interprets the data as a color, rendering a visual color representation.
- **`enumerator`**: Maps raw database values to user-friendly labels.
- **`foreign`**: Creates a relationship with another table for enhanced data display.
- **`data`** *(dict, optional)*: Contains additional information required for specific `type` values. Each type requires a different `data` structure:
- **`default`**: No `data` required (ignored if provided).
- **`color`**: No `data` required (ignored if provided).
- **`enumerator`**: A dictionary mapping raw database values (keys) to display labels (values). For example:
```yaml
data: {"active": "Active", "inactive": "Inactive"}
```
Here, a database value of `"active"` is displayed as `"Active"` in the frontend.
- **`foreign`**: Specifies the relationship details for joining with another table. Structure:
```yaml
data:
tableName: <string> # Name of the related table.
schemaName: <string> # Schema of the related table.
columnName: <string> # Column in the related table to join with.
columnDisplay: <string> # Column in the related table to display in the frontend.
```
Example:
```yaml
data:
tableName: "users"
schemaName: "public"
columnName: "id"
columnDisplay: "username"
```
This configuration joins the current table with the `users` table on the `id` column, displaying the `username` column instead of the raw `id`.
### About column definitions
You can set the `columnDef` property in the `Column` and `PrimaryKey` models and set the `defaultColDef` property in the `Config` and `Table` models.
The column definitions set in the `Config` model are applied to every table and column in the application, but they will be overwritten by the definitions set in the `Table`, and lastly overwritten by the definitions set in `Column` and `PrimaryKey`.
BananaManager does not offer support to every single definition of the original AG Grid, specially the Enterprise-only properties, but are some highlights that were fully tested:
- **editable** *(bool)* : Set to `true` if this column is editable, otherwise `false`.
- **hide** *(bool)* : Set to `true` for this column to be hidden.
- **sortable** *(bool)* : Set to `false` to disable sorting which is enabled by default.
- **filter** *(bool)* : Set to `true` to use the default filter component.
### Load the application
Create an app.py file in the root folder:
```python
from banana import Banana
app = Banana()
MY_PORT = 4000
if __name__ == "__main__":
app.run_server(port=MY_PORT)
```
This will load a development server in the selected port. Consider running a production server with `waitress`:
```python
from banana import Banana
from waitress import serve
app = Banana()
MY_PORT = 4000
if __name__ == "__main__":
serve(app.server, port=MY_PORT)
```
## Roadmap
| Version | Description | Release date |
|-----------|---------------------------------|----------------------------|
| **v0.1** | Load table and update cells | First half of July 2024 |
| **v0.2** | Table groups | Second half of July 2024 |
| **v0.3** | Logging and configurations | First half of August 2024 |
| **v0.4** | Insert rows and color themes | Second half of August 2024 |
| **v0.5** | Change history | September 2024 |
| **v0.6** | Color and enumerator data types | December 2024 |
| **v0.7** | Undo changes | First quarter of 2025 |
| **v0.8** | Delete rows | Second quarter of 2025 |
| **v0.9** | User authentication | 2025 |
| **v0.10** | Advanced user authorization | 2025 |
## License
Banana Manager is released under the MIT License. See the [LICENSE](LICENSE) file for more details.
Raw data
{
"_id": null,
"home_page": "https://github.com/GusFurtado/BananaManager",
"name": "banana-manager",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Gustavo Furtado",
"author_email": "gustavofurtado2@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/21/0e/277cbdc7b0f1683b06a7f6c1dee5ef7025f48c3ae1be5ce6137c591085fa/banana_manager-0.6.1.tar.gz",
"platform": null,
"description": "# \ud83c\udf4c Banana Manager\n\nWelcome to **Banana Manager**! Banana Manager is a Python package designed to connect to a database and create a simple web app that displays and allows updates to selected tables. This tool is perfect for non-technical end-users who need to interact with database tables without using complex DBA tools.\n\n\n## Powered by\n\n- **[Dash](https://dash.plotly.com/) and [AG Grid](https://www.ag-grid.com/)**: User-friendly, intuitive, and interactive web interface with powerful table displays and editing capabilities.\n- **[Pydantic](https://pydantic-docs.helpmanual.io/) and [YAML](https://yaml.org/)**: Fast and accurate data handling and configuration.\n- **[SQLAlchemy](https://www.sqlalchemy.org/)**: Secure, efficient, and flexible database operations for multiple database backends.\n\n\n## Installation\n\nTo install Banana Manager, simply use pip:\n\n```bash\npip install banana-manager\n```\n\nAlso, remember to install the appropriate database connector for your project, like `pyodbc` or `psycopg2`. If you\u2019re unsure, SQLAlchemy will inform you when you load your application.\n\nAdditionally, consider installing a production server like `waitress`:\n\n```bash\npip install waitress\n```\n\n## Getting started\n\nAt the end of this tutorial, you\u2019ll have a folder structure similar to the following:\n\n```\nmy_manager\n \u2514\u2500 app.py\n \u2514\u2500 config.yaml\n \u2514\u2500 my_tables\n \u2514\u2500 my_group_of_tables.yaml\n \u2514\u2500 another_group_of_tables.yaml\n```\n\n### Configuring the Manager\n\nCreate a `config.yaml` file in the root folder of your project with the following structure:\n\n```yaml\nconnection:\n drivername: <optional str>\n username: <optional str>\n password: <optional str>\n host: <optional str>\n port: <optional str>\n database: <optional str>\ndataPath: \"data\"\ntablePaths: [\"tables\"]\ntitle: \"Banana Database Manager\"\ntheme: <optional str>\ndefaultColDef: <optional dict>\ndefaultGridOptions: <optional dict>\n```\n\n- **connection** *(dict)* : This will create a [SQLAlchemy URL](https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.engine.URL) object. See the section [Dialets](https://docs.sqlalchemy.org/en/20/dialects/) for more information about the appropriate driver.\n- **dataPath** *(str, default=\"data\")* : The folder where the app data files will be stored.\n- **tablePaths** *(list[str], default=[\"tables\"])* : List of folder where the table models YAML files are stored.\n- **title** *(str, default=\"Banana Database Manager\")* : HTML header title attribute.\n- **theme** *(str, default=\"cyan\")* : One of the [default Mantine colors](https://mantine.dev/theming/colors/#default-colors).\n- **defaultColDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).\n- **defaultGridOptions** *(dict[str, Any])* : [AG Grid options](https://www.ag-grid.com/react-data-grid/grid-options/).\n\n### Defining the tables\n\nThe tables can be defined using YAML files located in the folders specified in the `config.yaml`. If no folder is specified, create a new folder named \"tables\" in the root folder.\n\nEach YAML file represents a group containing a list of tables. Here\u2019s the structure:\n\n```yaml\ngroupName: <optional string>\ndisplayOrder: <optional integer>\ntables:\n - name: <string>\n schemaName: <optional string>\n displayName: <optional string>\n columns:\n - name: <string>\n displayName: <optional string>\n dataType: (optional)\n data: <optional dict>\n type: <string>\n columnDef: <optional dict>\n - <other columns>\n orderBy: (optional)\n - column: <string>\n desc: <optional bool>\n - <other columns>\n limit: <optional int>\n defaultColDef: <optional dict>\n gridOptions: <optional dict>\n\n - <other tables>\n```\n\n#### Group configuration\n\n- **groupName** *(str, optional)* : Name of the group that will be displayed in the side menu.\n- **displayOrder** *(int, optional)* : Order which the groups will be stacked in the side menu.\n- **tables** *(list)* : List of table configurations.\n\n#### Table configuration\n\n- **name** *(str)* : Name of the table in the database.\n- **schemaName** *(str, optional)* : Schema where the table is located in the database.\n- **displayName** : *(str, optional)* : Name that will be displayed at the side menu.\n- **columns** *(list)* : List of column configurations.\n- **orderBy** *(list[dict])* : Default ordering of the table rows.\n- **limit** *(int)* : Maximum of rows returned after order by.\n- **defaultColDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).\n- **gridOptions** *(dict[str, Any])* : [AG Grid options](https://www.ag-grid.com/react-data-grid/grid-options/).\n\n#### Order by configuration\n\n- **column** *(str)* : Name of the column\n- **desc** *(bool, optional)* : If True, order table by column in descending order.\n\n#### Column configuration\n\n- **name** *(str)* : Name of the column in the database.\n- **displayName** *(str, optional)* : Name that will be displayed in the table.\n- **dataType** *(dict, optional)* : Set the column to one of the special data types.\n- **columnDef** *(dict[str, Any])* : [AG Grid column properties](https://www.ag-grid.com/angular-data-grid/column-properties/).\n\n#### Data type configuration\n\nThe `dataType` argument customizes how column data is interpreted and displayed. It consists of two keys:\n\n- **`type`** *(str)*: Specifies the data type. Available options are:\n - **`default`**: Standard data type, no special handling.\n - **`color`**: Interprets the data as a color, rendering a visual color representation.\n - **`enumerator`**: Maps raw database values to user-friendly labels.\n - **`foreign`**: Creates a relationship with another table for enhanced data display.\n\n- **`data`** *(dict, optional)*: Contains additional information required for specific `type` values. Each type requires a different `data` structure:\n - **`default`**: No `data` required (ignored if provided).\n - **`color`**: No `data` required (ignored if provided).\n - **`enumerator`**: A dictionary mapping raw database values (keys) to display labels (values). For example: \n ```yaml\n data: {\"active\": \"Active\", \"inactive\": \"Inactive\"}\n ```\n Here, a database value of `\"active\"` is displayed as `\"Active\"` in the frontend.\n - **`foreign`**: Specifies the relationship details for joining with another table. Structure:\n ```yaml\n data:\n tableName: <string> # Name of the related table.\n schemaName: <string> # Schema of the related table.\n columnName: <string> # Column in the related table to join with.\n columnDisplay: <string> # Column in the related table to display in the frontend.\n ```\n Example:\n ```yaml\n data:\n tableName: \"users\"\n schemaName: \"public\"\n columnName: \"id\"\n columnDisplay: \"username\"\n ```\n This configuration joins the current table with the `users` table on the `id` column, displaying the `username` column instead of the raw `id`.\n\n\n### About column definitions\n\nYou can set the `columnDef` property in the `Column` and `PrimaryKey` models and set the `defaultColDef` property in the `Config` and `Table` models.\n\nThe column definitions set in the `Config` model are applied to every table and column in the application, but they will be overwritten by the definitions set in the `Table`, and lastly overwritten by the definitions set in `Column` and `PrimaryKey`.\n\nBananaManager does not offer support to every single definition of the original AG Grid, specially the Enterprise-only properties, but are some highlights that were fully tested:\n\n- **editable** *(bool)* : Set to `true` if this column is editable, otherwise `false`.\n- **hide** *(bool)* : Set to `true` for this column to be hidden.\n- **sortable** *(bool)* : Set to `false` to disable sorting which is enabled by default.\n- **filter** *(bool)* : Set to `true` to use the default filter component.\n\n### Load the application\n\nCreate an app.py file in the root folder:\n\n```python\nfrom banana import Banana\n\napp = Banana()\nMY_PORT = 4000 \n\nif __name__ == \"__main__\":\n app.run_server(port=MY_PORT)\n```\n\nThis will load a development server in the selected port. Consider running a production server with `waitress`:\n\n```python\nfrom banana import Banana\nfrom waitress import serve\n\napp = Banana()\nMY_PORT = 4000\n\nif __name__ == \"__main__\":\n serve(app.server, port=MY_PORT)\n```\n\n\n## Roadmap\n\n| Version | Description | Release date |\n|-----------|---------------------------------|----------------------------|\n| **v0.1** | Load table and update cells | First half of July 2024 |\n| **v0.2** | Table groups | Second half of July 2024 |\n| **v0.3** | Logging and configurations | First half of August 2024 |\n| **v0.4** | Insert rows and color themes | Second half of August 2024 |\n| **v0.5** | Change history | September 2024 |\n| **v0.6** | Color and enumerator data types | December 2024 |\n| **v0.7** | Undo changes | First quarter of 2025 |\n| **v0.8** | Delete rows | Second quarter of 2025 |\n| **v0.9** | User authentication | 2025 |\n| **v0.10** | Advanced user authorization | 2025 |\n\n## License\n\nBanana Manager is released under the MIT License. See the [LICENSE](LICENSE) file for more details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Ready-to-go web app for end-users to interact with tables in a database.",
"version": "0.6.1",
"project_urls": {
"Homepage": "https://github.com/GusFurtado/BananaManager"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e91ed90051ae6e6e9f4c6ac5e5b06eeb4725e7e4ec193a8d743103d856cabb8a",
"md5": "1c1f9d07a7fe974f71fd4055930048a9",
"sha256": "f7554e9bdb3af792feb3b085fc2eb6b8d2ad6ab4cc2bf765203e5f4af35bd739"
},
"downloads": -1,
"filename": "banana_manager-0.6.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1c1f9d07a7fe974f71fd4055930048a9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 26708,
"upload_time": "2024-12-12T22:49:23",
"upload_time_iso_8601": "2024-12-12T22:49:23.293502Z",
"url": "https://files.pythonhosted.org/packages/e9/1e/d90051ae6e6e9f4c6ac5e5b06eeb4725e7e4ec193a8d743103d856cabb8a/banana_manager-0.6.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "210e277cbdc7b0f1683b06a7f6c1dee5ef7025f48c3ae1be5ce6137c591085fa",
"md5": "fb23048bb42f1df597318ba97a11856f",
"sha256": "61c37c52cb8ba334d6b23bfb1a301178ab641b7b7c12282dc2e66595a3ae78b0"
},
"downloads": -1,
"filename": "banana_manager-0.6.1.tar.gz",
"has_sig": false,
"md5_digest": "fb23048bb42f1df597318ba97a11856f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 21639,
"upload_time": "2024-12-12T22:49:24",
"upload_time_iso_8601": "2024-12-12T22:49:24.466941Z",
"url": "https://files.pythonhosted.org/packages/21/0e/277cbdc7b0f1683b06a7f6c1dee5ef7025f48c3ae1be5ce6137c591085fa/banana_manager-0.6.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-12 22:49:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "GusFurtado",
"github_project": "BananaManager",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "bidict",
"specs": []
},
{
"name": "dash",
"specs": []
},
{
"name": "dash-ag-grid",
"specs": []
},
{
"name": "dash-iconify",
"specs": []
},
{
"name": "dash-mantine-components",
"specs": [
[
"==",
"0.14.4"
]
]
},
{
"name": "Flask-SQLAlchemy",
"specs": []
},
{
"name": "pydantic",
"specs": []
},
{
"name": "sqlalchemy",
"specs": []
},
{
"name": "pyyaml",
"specs": []
}
],
"lcname": "banana-manager"
}