-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Framework/Gradio: Add basic example about Gradio, reading
sys.summits
- Loading branch information
Showing
9 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
name: Gradio | ||
|
||
on: | ||
pull_request: | ||
branches: ~ | ||
paths: | ||
- '.github/workflows/framework-gradio.yml' | ||
- 'framework/gradio/**' | ||
- '/requirements.txt' | ||
push: | ||
branches: [ main ] | ||
paths: | ||
- '.github/workflows/framework-gradio.yml' | ||
- 'framework/gradio/**' | ||
- '/requirements.txt' | ||
|
||
# Allow job to be triggered manually. | ||
workflow_dispatch: | ||
|
||
# Run job each night after CrateDB nightly has been published. | ||
schedule: | ||
- cron: '0 3 * * *' | ||
|
||
# Cancel in-progress jobs when pushing to the same branch. | ||
concurrency: | ||
cancel-in-progress: true | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
|
||
jobs: | ||
test: | ||
name: " | ||
Python: ${{ matrix.python-version }} | ||
CrateDB: ${{ matrix.cratedb-version }} | ||
on ${{ matrix.os }}" | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
os: [ 'ubuntu-latest' ] | ||
python-version: [ '3.10', '3.11', '3.12' ] | ||
cratedb-version: [ 'nightly' ] | ||
|
||
services: | ||
cratedb: | ||
image: crate/crate:${{ matrix.cratedb-version }} | ||
ports: | ||
- 4200:4200 | ||
- 5432:5432 | ||
env: | ||
CRATE_HEAP_SIZE: 4g | ||
|
||
steps: | ||
|
||
- name: Acquire sources | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
architecture: x64 | ||
cache: 'pip' | ||
cache-dependency-path: | | ||
requirements.txt | ||
framework/gradio/requirements.txt | ||
framework/gradio/requirements-dev.txt | ||
- name: Install utilities | ||
run: | | ||
pip install -r requirements.txt | ||
- name: Validate framework/gradio | ||
run: | | ||
ngr test --accept-no-venv framework/gradio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/flagged |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Gradio with CrateDB Example | ||
|
||
## About | ||
Demonstrate connectivity from Gradio to CrateDB. | ||
|
||
## Configuration | ||
Configure database connection address and credentials by using | ||
an SQLAlchemy connection string, see variable `CRATEDB_SQLALCHEMY_URL` | ||
in `basic_sys_summits.py`. Please make sure to use valid credentials | ||
matching your environment. | ||
|
||
## Usage | ||
|
||
### CrateDB on localhost | ||
To start a CrateDB instance on your machine, invoke: | ||
```shell | ||
docker run -it --rm \ | ||
--publish=4200:4200 --publish=5432:5432 \ | ||
--env=CRATE_HEAP_SIZE=2g \ | ||
crate:latest -Cdiscovery.type=single-node | ||
``` | ||
|
||
### CrateDB Cloud | ||
Please have a look at the [basic_sys_summits.py](basic_sys_summits.py) program | ||
as a blueprint. It includes a `CRATEDB_SQLALCHEMY_URL` variable definition | ||
that configures the application to connect to CrateDB Cloud. | ||
```python | ||
CRATEDB_SQLALCHEMY_URL = "crate://admin:g_,8.F0fNbVSk0.*!n54S5c,@example.gke1.us-central1.gcp.cratedb.net:4200?ssl=true"``` | ||
``` | ||
|
||
Install dependencies. | ||
```shell | ||
pip install -r requirements.txt | ||
``` | ||
|
||
Invoke Gradio to serve the application. | ||
```shell | ||
gradio basic_sys_summits.py | ||
``` | ||
|
||
## Screenshot | ||
|
||
Enjoy the list of mountains. | ||
|
||
![image](https://github.com/crate/cratedb-examples/assets/453543/af417966-b694-45ec-9391-f0e99a2ac014) | ||
|
||
|
||
## Development | ||
|
||
Acquire `cratedb-example` repository, and set up development sandbox. | ||
```shell | ||
git clone https://github.com/crate/cratedb-examples | ||
cd cratedb-examples | ||
python3 -m venv .venv | ||
source .venv/bin/activate | ||
pip install -r requirements.txt | ||
``` | ||
|
||
Invoke the integration test cases. | ||
```shell | ||
ngr test framework/gradio | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
""" | ||
A basic Gradio application connecting to CrateDB using SQLAlchemy. | ||
It reads the built-in `sys.summits` table into a dataframe, and | ||
displays its contents. | ||
- https://www.gradio.app/guides/connecting-to-a-database | ||
- https://www.gradio.app/docs/gradio/dataframe | ||
- https://cratedb.com/docs/sqlalchemy-cratedb/ | ||
""" | ||
import gradio as gr | ||
import pandas as pd | ||
|
||
# Connect to CrateDB on localhost. | ||
CRATEDB_SQLALCHEMY_URL = "crate://localhost:4200" | ||
|
||
# Connect to CrateDB Cloud. | ||
# CRATEDB_SQLALCHEMY_URL = "crate://admin:g_,8.F0fNbVSk0.*!n54S5c,@example.gke1.us-central1.gcp.cratedb.net:4200?ssl=true" | ||
|
||
|
||
def get_sys_summits(): | ||
""" | ||
Query the database using pandas. | ||
""" | ||
return pd.read_sql('SELECT * FROM "sys"."summits";', con=CRATEDB_SQLALCHEMY_URL) | ||
|
||
|
||
def get_dataframe(): | ||
""" | ||
Create a dataframe widget. | ||
""" | ||
df = get_sys_summits() | ||
return gr.DataFrame(df) | ||
|
||
|
||
# Define the Gradio interface. | ||
demo = gr.Interface( | ||
fn=get_dataframe, | ||
inputs=[], | ||
outputs=["dataframe"], | ||
title="Gradio with CrateDB Example", | ||
live=True, | ||
allow_flagging="never", | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
demo.launch() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[tool.pytest.ini_options] | ||
minversion = "2.0" | ||
addopts = """ | ||
-rfEX -p pytester --strict-markers --verbosity=3 | ||
--capture=no | ||
""" | ||
log_level = "DEBUG" | ||
log_cli_level = "DEBUG" | ||
testpaths = ["*.py"] | ||
xfail_strict = true | ||
markers = [ | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gradio-client==1.0.* | ||
pytest<9 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gradio==4.* | ||
sqlalchemy-cratedb==0.38.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import logging | ||
import shlex | ||
import subprocess | ||
import sys | ||
import threading | ||
import time | ||
from urllib.error import HTTPError | ||
from urllib.request import urlopen | ||
|
||
import pytest | ||
from gradio_client import Client | ||
|
||
|
||
logger = logging.getLogger() | ||
|
||
GRADIO_SERVER_PORT = "7861" | ||
GRADIO_API_URL = f"http://localhost:{GRADIO_SERVER_PORT}" | ||
|
||
|
||
def run(command: str, env=None, timeout: int = None): | ||
""" | ||
Invoke a command in a subprocess. | ||
""" | ||
env = env or {} | ||
env["PATH"] = "" | ||
subprocess.call(shlex.split(command), env=env, timeout=timeout) | ||
|
||
|
||
def check_url(url): | ||
""" | ||
Check if a service is reachable. | ||
Makes a simple GET request to path of the HTTP endpoint. Service is | ||
available if returned status code is < 500. | ||
""" | ||
try: | ||
r = urlopen(url) | ||
return r.code < 500 | ||
except HTTPError as e: | ||
# If service returns e.g. a 404 it's ok | ||
return e.code < 500 | ||
except Exception: | ||
# Possible service not yet started | ||
return False | ||
|
||
|
||
@pytest.fixture(scope="session", autouse=True) | ||
def run_server(): | ||
|
||
def server_thread(): | ||
print("sys.exec:", sys.executable) | ||
try: | ||
run(f"{sys.executable} basic_sys_summits.py", env={"GRADIO_SERVER_PORT": GRADIO_SERVER_PORT}, timeout=5) | ||
except subprocess.TimeoutExpired: | ||
pass | ||
|
||
thread = threading.Thread(target=server_thread) | ||
try: | ||
thread.start() | ||
except KeyboardInterrupt: | ||
pass | ||
|
||
while not check_url(GRADIO_API_URL): | ||
logger.info("Waiting for Gradio API to come up") | ||
time.sleep(0.2) | ||
|
||
|
||
def test_read_sys_summits(): | ||
""" | ||
Verify reading CrateDB's built-in `sys.summits` database table through the Gradio API. | ||
- https://www.gradio.app/guides/getting-started-with-the-python-client | ||
- https://www.gradio.app/docs/python-client/ | ||
- https://www.gradio.app/docs/gradio/dataframe | ||
""" | ||
|
||
# Connect to Gradio API, and submit a request. | ||
client = Client(GRADIO_API_URL) | ||
result = client.predict(api_name="/predict") | ||
|
||
# Verify result. | ||
assert "mountain" in result["value"]["headers"] | ||
assert len(result["value"]["data"]) > 80 | ||
assert result["value"]["data"][0][5] == "Mont Blanc" |