├── .gitignore ├── LICENSE.md ├── README.md ├── docker-compose.yml ├── files └── demo.db ├── pyproject.py.toml ├── ruff.toml ├── scripts └── ansible │ ├── Makefile │ ├── README.md │ └── deploy-to-vm.yml ├── start.sh ├── worker ├── Dockerfile ├── README.md ├── inside_docker.py ├── requirements-custom.txt └── requirements.txt └── workspace ├── __init__.py ├── demo ├── __init__.py ├── page1 │ ├── __init__.py │ ├── functions.py │ ├── main.py │ ├── state.py │ └── store.py └── properties.json └── properties.json /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | 3 | .idea 4 | .vscode 5 | .DS_Store 6 | .coverage* 7 | !.coveragerc 8 | 9 | *.pyc 10 | *.ipynb 11 | *.env 12 | *.env.* 13 | 14 | .venv 15 | *node_modules/ 16 | notebooks/ 17 | 18 | workspace/* 19 | !workspace/demo/ 20 | !workspace/__init__.py 21 | !workspace/properties.json 22 | dump.rdb 23 | server.toml 24 | worker.toml 25 | 26 | files/dev.db -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | DROPBASE SOFTWARE LICENSE (DSL) 2 | 3 | This Software License Agreement (the "Agreement") is entered into between the end-user ("Licensee") and Castodia Inc., doing business as Dropbase ("Licensor"). 4 | 5 | The Agreement specifies the terms under which Licensor permits the Licensee to engage with and modify the software source code (the "Software"), a component of Licensor's software services. 6 | 7 | By using the Software, Licensee confirms they have read this Agreement, understand it, and consent to be bound by its terms, which shall also bind their successors and assigns as permitted herein. Licensee concurrently acknowledges acceptance of the Licensor’s standard Terms of Service, which are incorporated by reference into this Agreement. Licensee's continued use of the Software signifies ongoing agreement to the Terms of Service as updated from time to time. 8 | 9 | By agreeing to the terms of this Agreement, you represent and warrant the Licensor that you have full authority to enter this Agreement. You agree to comply with all of these terms and conditions upon any use of the software. 10 | 11 | "Licensee" shall refer to either the individual or the entity that is utilizing the Software as permitted herein. 12 | 13 | 1. LICENSE GRANT 14 | 15 | Pursuant to the conditions of this Agreement, the Licensor grants to Licensee a non-exclusive, royalty-free, non-assignable, non-sublicensable license to: 16 | 17 | (a) Download, use, view, alter, and deploy the Software's source code exclusively for configuring a self-hosted service that integrates with Dropbase's services, as intended by Dropbase. 18 | 19 | 2. NOTICE REQUIREMENTS 20 | 21 | When modifying the Software, Licensee must: 22 | 23 | (a) Maintain and prominently display the original notice on all copies of the Software, which declares: "This Software is made available by Dropbase under the terms of the Dropbase Software License Agreement." 24 | 25 | 3. USE RESTRICTIONS 26 | 27 | Licensee is expressly forbidden from: 28 | 29 | (a) Incorporating, modifying, or using the Software as part of any other product or service; 30 | 31 | (b) Creating any kind of SaaS, PaaS, IaaS, or comparable services using the Software's code; 32 | 33 | (c) Utilizing any segment of the Software's code to directly compete with or develop competing software, products, or services against Dropbase. 34 | 35 | 4. OWNERSHIP AND INTELLECTUAL PROPERTY 36 | 37 | All rights, titles, and interests, including all intellectual property rights, pertaining to the Software shall exclusively remain with Dropbase. No other rights are granted under this Agreement aside from those explicitly outlined herein. 38 | 39 | 5. NON-ASSIGNABILITY 40 | 41 | Licensee shall not assign any rights or obligations under this Agreement without the prior written consent of the Licensor. Licensor may assign its rights and obligations under this Agreement at its sole discretion. 42 | 43 | 6. TERMINATION 44 | 45 | This Agreement may be terminated by Licensor without notice if Licensee fails to adhere to any term or condition contained herein. 46 | 47 | 7. WARRANTY DISCLAIMER 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED. 50 | 51 | 8. LIMITATION OF LIABILITY 52 | 53 | IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, TO THE MAXIMUM EXTENT PERMITTED BY LAW. 54 | 55 | 9. ENTIRE AGREEMENT 56 | 57 | This Agreement constitutes the complete and exclusive agreement between the parties regarding the use of the Software. 58 | 59 | Neither the discovery nor the inspection of the source code shall imply a license under any of Licensor's or third-party intellectual property rights, except as stated in this Agreement. 60 | 61 | 10. GOVERNING LAW 62 | 63 | This Agreement shall be governed and interpreted in accordance with the laws of the jurisdiction where Licensor's principal business is located. 64 | 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Dropbase logo 4 | 5 |

6 | 7 |

AI-Based Python Web App Builder

8 | 9 |

10 | Website · Docs · Discord

11 | 12 |

13 | 14 | Dropbase hero 15 | 16 |

17 | 18 | # Overview 19 | 20 | Dropbase helps you build and prototype web apps faster with AI. Developers can quickly build anything from admin panels, back-office tools, billing dashboards, and internal engineering tools that can fetch data from data sources and trigger action across any internal or external service. 21 | 22 | Existing low-code/no code tools lack flexibility, confine devs to building app logic by filling up UI forms, and have big learning curves. Dropbase uses AI to generate app code that you can verify and/or edit. We combine the convenience of a drag-and-drop app builder with the flexibility of code, making it easy to build and customize, while learning to use the product as you see how the AI generates code using the Dropbase web framework. 23 | 24 | ## Why Dropbase? 25 | 26 | 1. Write (or generate) any custom business logic with code. 27 | 2. Built-in web framework with pre-built UI components - no need to hassle with frontend libraries/code. 28 | 3. Local-first, self-hosted. No creds are shared with us. 29 | 4. Dropbase lives in your codebase, making it easy to import or resuse custom scripts/libraries. 30 | 5. Apps are portable: app folders can be zipped and shared to other Dropbase users 31 | 6. It's built on Python and you can import any PyPI package. 32 | 33 | ## Demo 34 | 35 | ### Order Dashboard with Integrations to Mailgun and Slack 36 | 37 | In this demo, we show developers how to build a tool to lookup customers orders, and send order info via a email or a Slack channel 38 | 39 | 40 | 41 | 42 | 43 | ### Salesforce Leads Editor 44 | 45 | In this demo, we show developers how to build an app to edit Salesforce leads in a spreadsheet interface 46 | 47 | 48 | 49 | 50 | 51 | ### HubSpot Contacts Editor 52 | 53 | In this demo, we show developers how to build an app to edit HubSpot contacts in a spreadsheet interface 54 | 55 | 56 | 57 | 58 | 59 | 60 | ### Build an orders app that uses charts 61 | 62 | 63 | 64 | 65 | 66 | ## Get Started 67 | 68 | ### 0. Pre-requisites 69 | 70 | - Install Docker. We strongly recommend using [Docker Desktop](https://www.docker.com/products/docker-desktop/), especially if you're on Apple M chips. Alternatively, you can install `docker` and `docker-compose`. 71 | 72 | ### 1. Clone the `dropbase` repo 73 | 74 | Clone the Dropbase repository 75 | 76 | ```python 77 | git clone https://github.com/DropbaseHQ/dropbase.git 78 | ``` 79 | 80 | ### 2. Start the server 81 | 82 | Start the server by running start.sh 83 | 84 | **NOTE:** When starting the server for the first time, make `start.sh` executable. 85 | 86 | ```bash 87 | chmod +x start.sh 88 | ``` 89 | 90 | You can start the server by running 91 | 92 | ```bash 93 | ./start.sh 94 | ``` 95 | 96 | ### 3. Create your first Dropbase app 97 | 98 | Go to the Dropbase App `http://localhost:3030/apps` from your browser and click on the `Create app` button to create your first Dropbase app. 99 | 100 | ## Enabling AI features 101 | 102 | Dropbase uses LLM (gpt, sonnet) to provide AI Developer feature. To enable it, add your OpenAI or Anthropic api key into `server.toml`. Example: 103 | 104 | ```bash 105 | [llm.openai] 106 | api_key = "YOUR_API_KEY" 107 | model = "gpt-4o" 108 | ``` 109 | 110 | **IMPORTANT:** If you add additional environmental variables, make sure to add them before LLM configurations (at the top-level table), since LLM configurations are defined as [table](https://toml.io/en/v1.0.0#table) 111 | 112 | ## Configuring Worker 113 | 114 | `worker.toml` contains environmental variables for the worker. This includes database sources, API keys, or access token to third party services. 115 | 116 | > [!IMPORTANT] 117 | > If you're upgrading to dropbase-server >v0.6.0, please ensure that `worker.toml` is in your `workspace` directory. 118 | 119 | To include API keys or tokens, add a name for the token and enter your string token. Though not required, adding a descriptive name helps Dropbase AI infer the key to use. 120 | 121 | ```bash 122 | stripe_key="rk_test_123" 123 | mailgun_api_key="abc123" 124 | ``` 125 | 126 | To include database sources, use the following format: `database`.`database_type`.`database_nickname` 127 | 128 | For example, if you want to add a `postgres` database to a list of sources and use `my_source` as its nickname, add the following: 129 | 130 | ```bash 131 | [database.postgres.my_source] 132 | host = "localhost" 133 | database = "postgres" 134 | username = "username" 135 | password = "password" 136 | port = 5432 137 | ``` 138 | 139 | **NOTE:** The built-in demo requires `database.sqlite.demo` to be present in `worker.toml`. 140 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | dropbase-client: 3 | image: dropbase/client:0.6.7 4 | ports: 5 | - "3030:80" 6 | depends_on: 7 | - dropbase-lsp 8 | dropbase-server: 9 | image: dropbase/server:0.6.7 10 | volumes: 11 | - ./workspace:/project/workspace 12 | - ./files:/project/files 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - ./server.toml:/project/server.toml 15 | - ./pyproject.py.toml:/project/pyproject.py.toml 16 | ports: 17 | - "9090:9090" 18 | environment: 19 | - PYTHONUNBUFFERED=1 20 | - REDIS_HOST=redis 21 | - HOST_PATH=${HOST_PATH} 22 | dropbase-lsp: 23 | image: dropbase/lsp:0.1.1 24 | volumes: 25 | - ./workspace:/project/workspace 26 | - ./files:/project/files 27 | - ./ruff.toml:/project/ruff.toml 28 | - /var/run/docker.sock:/var/run/docker.sock 29 | # Attach custom volumes here 30 | environment: 31 | - PYTHONUNBUFFERED=1 32 | ports: 33 | - "9095:9095" 34 | redis: 35 | image: redis 36 | ports: 37 | - 6379:6379 -------------------------------------------------------------------------------- /files/demo.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DropbaseHQ/dropbase/31a1bfb329c7ad2b95be901380c23153010d840b/files/demo.db -------------------------------------------------------------------------------- /pyproject.py.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 105 3 | include = '\.pyi?$' 4 | exclude = ''' 5 | ^(lsp|alembic)/ 6 | ''' 7 | target-version = ['py311'] 8 | -------------------------------------------------------------------------------- /ruff.toml: -------------------------------------------------------------------------------- 1 | # Exclude a variety of commonly ignored directories. 2 | exclude = [ 3 | ".bzr", 4 | ".direnv", 5 | ".eggs", 6 | ".git", 7 | ".git-rewrite", 8 | ".hg", 9 | ".ipynb_checkpoints", 10 | ".mypy_cache", 11 | ".nox", 12 | ".pants.d", 13 | ".pyenv", 14 | ".pytest_cache", 15 | ".pytype", 16 | ".ruff_cache", 17 | ".svn", 18 | ".tox", 19 | ".venv", 20 | ".vscode", 21 | "__pypackages__", 22 | "_build", 23 | "buck-out", 24 | "build", 25 | "dist", 26 | "node_modules", 27 | "site-packages", 28 | "venv", 29 | ] 30 | 31 | # Same as Black. 32 | line-length = 88 33 | indent-width = 4 34 | 35 | # Assume Python 3.11 36 | target-version = "py311" 37 | 38 | [lint] 39 | # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. 40 | # Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or 41 | # McCabe complexity (`C901`) by default. 42 | select = ["E4", "E7", "E9", "F"] 43 | ignore = ["F403", "F405"] 44 | 45 | # Allow fix for all enabled rules (when `--fix`) is provided. 46 | fixable = ["ALL"] 47 | unfixable = [] 48 | 49 | # Allow unused variables when underscore-prefixed. 50 | dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" 51 | 52 | [format] 53 | # Like Black, use double quotes for strings. 54 | quote-style = "double" 55 | 56 | # Like Black, indent with spaces, rather than tabs. 57 | indent-style = "space" 58 | 59 | # Like Black, respect magic trailing commas. 60 | skip-magic-trailing-comma = false 61 | 62 | # Like Black, automatically detect the appropriate line ending. 63 | line-ending = "auto" 64 | 65 | # Enable auto-formatting of code examples in docstrings. Markdown, 66 | # reStructuredText code/literal blocks and doctests are all supported. 67 | # 68 | # This is currently disabled by default, but it is planned for this 69 | # to be opt-out in the future. 70 | docstring-code-format = false 71 | 72 | # Set the line length limit used when formatting code snippets in 73 | # docstrings. 74 | # 75 | # This only has an effect when the `docstring-code-format` setting is 76 | # enabled. 77 | docstring-code-line-length = "dynamic" 78 | -------------------------------------------------------------------------------- /scripts/ansible/Makefile: -------------------------------------------------------------------------------- 1 | deploy: 2 | ifndef host 3 | $(error host is not defined. Please provide your server address.) 4 | endif 5 | ifndef user 6 | $(error user is not defined. Please provide user to login into the server.) 7 | endif 8 | 9 | ansible-playbook deploy-to-vm.yml -i $(host), -e "ansible_user=$(user)" -e "ansible_password=$(password)" -e "ansible_ssh_private_key_file=$(ssh_key_file)" 10 | -------------------------------------------------------------------------------- /scripts/ansible/README.md: -------------------------------------------------------------------------------- 1 | ## Dropbase deployment using Ansible 2 | 3 | ### Prerequisites 4 | 5 | Make sure you have `.env` file on the project's root directory. The file must contain the two following environment variables: 6 | ```bash 7 | DROPBASE_API_URL="https://api.dropbase.io" 8 | DROPBASE_TOKEN='' 9 | ``` 10 | 11 | Make sure you have ansible installed on your machine where you will run the deployment. You can install ansible using 12 | the following command: 13 | 14 | ```bash 15 | pip3 install ansible 16 | ``` 17 | 18 | It's recommended to authenticate to your server using a SSH key-pair. However, you are using username/password 19 | authentication, make sure you have sshpass installed. 20 | 21 | ```bash 22 | # on MacOS X 23 | brew install hudochenkov/sshpass/sshpass 24 | 25 | # on Ubuntu 26 | apt-get install sshpass 27 | ``` 28 | 29 | ### Deploy dropbase to your server 30 | 31 | Before you deploy, make sure you can authenticate to the server using a user has sudo privileges. 32 | 33 | You should [enable passwordless sudo](https://timonweb.com/devops/how-to-enable-passwordless-sudo-for-a-specific-user-in-linux/) so that you don't have to enter the password every time the script runs a new step. 34 | 35 | ```bash 36 | make deploy \ 37 | host=your_server_ip \ 38 | user=your_server_user \ 39 | ssh_key_file=your_private_ssh_key_file # if you use a custom \ 40 | password=your_server_user_password # only for user/password authentication 41 | ``` 42 | -------------------------------------------------------------------------------- /scripts/ansible/deploy-to-vm.yml: -------------------------------------------------------------------------------- 1 | - name: Deploy new dropbase to linux machine 2 | hosts: all 3 | gather_facts: yes 4 | become: yes 5 | vars: 6 | deploy_user: "{{ ansible_user }}" 7 | deploy_dir: "/opt/dropbase" 8 | 9 | tasks: 10 | - name: Debug message 11 | debug: 12 | msg: Using {{ deploy_user }} user to deploy dropbase to {{ ansible_host }} 13 | 14 | - name: Add Docker GPG apt Key (Ubuntu) 15 | apt_key: 16 | url: https://download.docker.com/linux/ubuntu/gpg 17 | state: present 18 | when: ansible_distribution == 'Ubuntu' 19 | 20 | - name: Add repository into sources list (Ubuntu) 21 | apt_repository: 22 | repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable 23 | state: present 24 | filename: docker 25 | when: ansible_distribution == 'Ubuntu' 26 | 27 | - name: Install Docker (Ubuntu) 28 | apt: 29 | name: 30 | - docker-ce 31 | - docker-ce-cli 32 | - containerd.io 33 | state: present 34 | update_cache: true 35 | when: ansible_distribution == 'Ubuntu' 36 | 37 | - name: Install Docker (Amazon Linux) 38 | package: 39 | name: 40 | - docker 41 | state: latest 42 | when: ansible_distribution == 'Amazon' 43 | 44 | - name: Install required packages 45 | package: 46 | name: 47 | - python3-pip 48 | state: latest 49 | 50 | - name: Remove python3-requests # amazon linux uses an old version of requests 51 | package: 52 | name: python3-requests 53 | state: absent 54 | 55 | - name: Install pip packages 56 | pip: 57 | name: 58 | - docker==6.1.3 59 | - docker-compose==1.29.2 60 | - urllib3==1.26.18 61 | 62 | - name: Make sure deploy user belong to group and "docker" group 63 | user: 64 | name: "{{ deploy_user }}" 65 | groups: 66 | - docker 67 | append: yes 68 | become: yes 69 | 70 | - name: Make sure docker service is enabled and started 71 | service: 72 | name: docker 73 | state: started 74 | enabled: yes 75 | 76 | - name: Make sure dropbase folder exists 77 | file: 78 | path: "{{ deploy_dir }}" 79 | state: directory 80 | mode: "0755" 81 | owner: "{{ ansible_user }}" 82 | group: "{{ ansible_user }}" 83 | 84 | - name: Create docker-compose.yml file 85 | template: 86 | src: ../../docker-compose.yml 87 | dest: "{{ deploy_dir }}/docker-compose.yml" 88 | owner: "{{ deploy_user }}" 89 | group: "{{ deploy_user }}" 90 | mode: "0644" 91 | 92 | - name: Copy requirements-custom.txt to the server 93 | copy: 94 | src: ../../requirements-custom.txt 95 | dest: "{{ deploy_dir }}/requirements-custom.txt" 96 | owner: "{{ deploy_user }}" 97 | group: "{{ deploy_user }}" 98 | 99 | - name: Synchronize workspace to the server 100 | synchronize: 101 | src: ../../workspace 102 | dest: "{{ deploy_dir }}" 103 | delete: true 104 | become: false 105 | 106 | - name: Synchronize files to the server 107 | synchronize: 108 | src: ../../files 109 | dest: "{{ deploy_dir }}" 110 | delete: true 111 | become: false 112 | 113 | - name: Create app .env file 114 | copy: 115 | src: ../../.env 116 | dest: "{{ deploy_dir }}/.env" 117 | owner: "{{ deploy_user }}" 118 | group: "{{ deploy_user }}" 119 | mode: "0644" 120 | 121 | - name: Updating CORS_ORIGINS environment variables 122 | lineinfile: 123 | path: "{{ deploy_dir }}/.env" 124 | regexp: "^CORS_ORIGINS=" 125 | line: CORS_ORIGINS='["http://{{ ansible_host }}:3030", "http://www.{{ ansible_host }}:3030", "https://try.dropbase.io"]' 126 | 127 | - name: Synchronize worker to the server 128 | synchronize: 129 | src: ../../worker 130 | dest: "{{ deploy_dir }}" 131 | delete: true 132 | become: false 133 | 134 | - name: Build worker image 135 | shell: docker build -t dropbase/worker "{{ deploy_dir }}/worker" 136 | 137 | - name: Pull and start the docker containers 138 | community.docker.docker_compose: 139 | project_src: "{{ deploy_dir }}" 140 | build: false 141 | pull: true 142 | environment: 143 | HOST_WORKSPACE_PATH: "{{ deploy_dir }}" 144 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set working directory path 4 | WORKING_DIR=$(pwd) 5 | 6 | # Define configuration file paths 7 | SERVER_TOML="server.toml" 8 | WORKER_TOML="workspace/worker.toml" 9 | 10 | # Check and create server.toml if necessary 11 | if [ ! -f "$SERVER_TOML" ]; then 12 | echo "Creating $SERVER_TOML..." 13 | cat < "$SERVER_TOML" 14 | host_path = "$WORKING_DIR" 15 | host_mounts = [] 16 | redis_host = "redis" 17 | task_timeout = 600 18 | 19 | [llm.openai] 20 | api_key = "YOUR_API_KEY" 21 | model = "gpt-4o" 22 | 23 | # For Anthropic models 24 | # [llm.anthropic] 25 | # api_key = "YOUR_API_KEY" 26 | # model = "claude-3-5-sonnet-20240620" 27 | EOL 28 | else 29 | echo "$SERVER_TOML already exists." 30 | fi 31 | 32 | # Check and create worker.toml if necessary 33 | if [ ! -f "$WORKER_TOML" ]; then 34 | echo "Creating $WORKER_TOML..." 35 | cat < "$WORKER_TOML" 36 | [database.sqlite.demo] 37 | host = "files/demo.db" 38 | EOL 39 | else 40 | echo "$WORKER_TOML already exists." 41 | fi 42 | 43 | # check files/dev.db exists and create if necessary 44 | if [ ! -f "files/dev.db" ]; then 45 | echo "Creating files/dev.db..." 46 | touch "files/dev.db" 47 | else 48 | echo "files/dev.db already exists." 49 | fi 50 | 51 | 52 | # build dropbase/worker 53 | docker image rm dropbase/worker 54 | docker build -t dropbase/worker worker/. 55 | 56 | # Set host path 57 | export HOST_PATH=$(pwd) 58 | 59 | # Start containers 60 | docker compose up -------------------------------------------------------------------------------- /worker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Python runtime as a parent image 2 | FROM python:3.11-slim 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy the current directory contents into the container at /app 8 | ADD . . 9 | 10 | # Install packages 11 | RUN pip install --no-cache-dir --upgrade -r requirements.txt 12 | RUN pip install --no-cache-dir --upgrade -r requirements-custom.txt 13 | 14 | CMD tail -f /dev/null -------------------------------------------------------------------------------- /worker/README.md: -------------------------------------------------------------------------------- 1 | ## build new docker 2 | 3 | ``` 4 | docker build -t dropbase/worker:latest . 5 | ``` 6 | -------------------------------------------------------------------------------- /worker/inside_docker.py: -------------------------------------------------------------------------------- 1 | import redis 2 | from dotenv import load_dotenv 3 | 4 | from dropbase.worker.run_python import run 5 | 6 | load_dotenv() 7 | 8 | 9 | if __name__ == "__main__": 10 | # NOTE: we need to use host.docker.internal to connect to the host machine's redis. tested on mac 11 | r = redis.Redis(host="host.docker.internal", port=6379, db=0) 12 | run(r) 13 | -------------------------------------------------------------------------------- /worker/requirements-custom.txt: -------------------------------------------------------------------------------- 1 | # your custom packages here -------------------------------------------------------------------------------- /worker/requirements.txt: -------------------------------------------------------------------------------- 1 | toml==0.10.2 2 | pandas==2.2.2 3 | astor==0.8.1 4 | redis==5.0.1 5 | sqlalchemy==1.4.46 6 | pydantic==2.8.2 7 | python-dotenv==1.0.0 8 | requests==2.31.0 9 | plotly==5.22.0 10 | dropbase==0.6.4 11 | -------------------------------------------------------------------------------- /workspace/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DropbaseHQ/dropbase/31a1bfb329c7ad2b95be901380c23153010d840b/workspace/__init__.py -------------------------------------------------------------------------------- /workspace/demo/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import os 3 | import pkgutil 4 | 5 | for importer, modname, ispkg in pkgutil.iter_modules([os.path.dirname(__file__)]): 6 | module_dir = os.path.join(os.path.dirname(__file__), modname) 7 | if ispkg and os.path.exists(module_dir): 8 | importlib.import_module(f".{modname}", __package__) 9 | -------------------------------------------------------------------------------- /workspace/demo/page1/__init__.py: -------------------------------------------------------------------------------- 1 | from .state import State 2 | from .store import Store 3 | -------------------------------------------------------------------------------- /workspace/demo/page1/functions.py: -------------------------------------------------------------------------------- 1 | from .state import State 2 | from dropbase.database.connect import connect 3 | import pandas as pd 4 | 5 | # functions 6 | def on_click(state: State) -> State: 7 | state.page.message = "Great!" 8 | state.page.message_status = "info" 9 | return state 10 | 11 | 12 | def get_table_data(state: State) -> State: 13 | db = connect("demo") 14 | table_data = db.query("SELECT * FROM orders") 15 | table_df = pd.DataFrame(table_data) 16 | state.table1.data = table_df.to_dict(orient="records") 17 | return state 18 | -------------------------------------------------------------------------------- /workspace/demo/page1/main.py: -------------------------------------------------------------------------------- 1 | from dropbase.models.models import * 2 | from .functions import * 3 | 4 | 5 | page = Page( 6 | id="page1", 7 | name="Page 1", 8 | on_load=get_table_data, 9 | blocks=( 10 | Table(id="table1", label="Table1", w=10, h=4, x=0, y=0, visible=True, on_row_change=None, columns=[]), 11 | Button(id="button1", label="Button1", w=2, h=1, x=10, y=0, visible=True, on_click=on_click), 12 | ), 13 | ) 14 | -------------------------------------------------------------------------------- /workspace/demo/page1/state.py: -------------------------------------------------------------------------------- 1 | from dropbase.models.state import * 2 | from pydantic import BaseModel 3 | from .store import Store 4 | 5 | 6 | class State(BaseModel): 7 | page: PageState 8 | store: Store 9 | table1: TableState 10 | button1: ButtonState 11 | -------------------------------------------------------------------------------- /workspace/demo/page1/store.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | from pydantic import BaseModel 4 | 5 | 6 | class Store(BaseModel): 7 | """ 8 | Please make sure to either user Optional or provide default values 9 | For example: 10 | ``` 11 | name: str = "" # default value for name is an empty string 12 | # or 13 | name: Optional[str] # name is optional 14 | ``` 15 | If no default value is provided and the field is not Optional, 16 | the system will assume the default value based on type. 17 | For example: int -> 0, str -> "", bool -> True 18 | """ 19 | 20 | pass 21 | -------------------------------------------------------------------------------- /workspace/demo/properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "page1": { 3 | "label": "Page 1" 4 | } 5 | } -------------------------------------------------------------------------------- /workspace/properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "apps": { 3 | "demo": { 4 | "label": "Demo" 5 | } 6 | } 7 | } 8 | --------------------------------------------------------------------------------