fmegahed commited on
Commit
46a7205
·
verified ·
1 Parent(s): 72dcfa6

Uploading the DockerFile, app.R, and README.md

Browse files
Files changed (3) hide show
  1. Dockerfile +39 -0
  2. README.md +117 -12
  3. app.R +58 -0
Dockerfile ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM rocker/shiny:4.5.2
2
+
3
+ # System dependencies for querychat/duckdb
4
+ RUN apt-get update && apt-get install -y \
5
+ libcurl4-openssl-dev \
6
+ libssl-dev \
7
+ libxml2-dev \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ WORKDIR /app
11
+
12
+ # Install remotes for version-pinned installation
13
+ RUN R -e "install.packages('remotes', repos='https://cloud.r-project.org')"
14
+
15
+ # Install CRAN packages with pinned versions
16
+ RUN R -e "remotes::install_version('shiny', version = '1.12.1', repos = 'https://cloud.r-project.org')"
17
+ RUN R -e "remotes::install_version('bslib', version = '0.10.0', repos = 'https://cloud.r-project.org')"
18
+ RUN R -e "remotes::install_version('DT', version = '0.34.0', repos = 'https://cloud.r-project.org')"
19
+ RUN R -e "remotes::install_version('dplyr', version = '1.2.0', repos = 'https://cloud.r-project.org')"
20
+ # duckdb - install from duckdb r-universe with pinned version
21
+ RUN R -e "remotes::install_version('duckdb', version = '1.4.4', repos = c('https://duckdb.r-universe.dev', 'https://cloud.r-project.org'))"
22
+
23
+ # Install r-universe packages with pinned versions (querychat and dependencies)
24
+ RUN R -e "remotes::install_version('ellmer', version = '0.4.0', repos = c('https://posit-dev.r-universe.dev', 'https://cloud.r-project.org'))"
25
+ RUN R -e "remotes::install_version('shinychat', version = '0.3.0', repos = c('https://posit-dev.r-universe.dev', 'https://cloud.r-project.org'))"
26
+ RUN R -e "remotes::install_version('querychat', version = '0.2.0', repos = c('https://posit-dev.r-universe.dev', 'https://cloud.r-project.org'))"
27
+
28
+ # Copy application code
29
+ COPY app.R app.R
30
+ COPY data/ data/
31
+ COPY www/ www/
32
+
33
+ # Verify critical packages are available
34
+ RUN R -e "stopifnot(requireNamespace('shiny', quietly = TRUE))" \
35
+ && R -e "stopifnot(requireNamespace('querychat', quietly = TRUE))"
36
+
37
+ EXPOSE 7860
38
+
39
+ CMD ["R", "--quiet", "-e", "shiny::runApp('/app', host='0.0.0.0', port=7860)"]
README.md CHANGED
@@ -1,12 +1,117 @@
1
- ---
2
- title: Querychat Demo
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: red
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- short_description: A short demo for using querychat for Miami Students
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ sdk: docker
3
+ app_port: 7860
4
+ title: ISA 401 OEWS Jobs Explorer
5
+ emoji: 📊
6
+ colorFrom: yellow
7
+ colorTo: yellow
8
+ pinned: false
9
+ license: mit
10
+ short_description: Explore U.S. occupational employment and wage data
11
+ ---
12
+
13
+ # ISA 401 OEWS Jobs Explorer
14
+
15
+ **Your AI-Powered Assistant for Exploring Occupational Employment and Wage Statistics**
16
+
17
+ [![Live App](https://img.shields.io/badge/Live_App-Hugging_Face-yellow)](https://huggingface.co/spaces/fmegahed/oews_explorer)
18
+
19
+ Explore the U.S. Bureau of Labor Statistics' Occupational Employment and Wage Statistics (OEWS) dataset using natural language queries.
20
+
21
+ ---
22
+
23
+ ## What is this app?
24
+
25
+ This Shiny application uses AI-powered natural language processing to help you explore the OEWS dataset. Instead of writing SQL queries, simply ask questions in plain English and get instant results.
26
+
27
+ **Example queries:**
28
+ - "What are the top 10 highest paying occupations in Ohio?"
29
+ - "Show me employment by industry for software developers"
30
+ - "What is the median wage for nurses nationally?"
31
+ - "Compare wages between California and Texas for data scientists"
32
+
33
+ ---
34
+
35
+ ## Dataset Information
36
+
37
+ **Dataset:** Occupational Employment and Wage Statistics (OEWS) Survey (May 2024 Estimates)
38
+ **Publisher:** U.S. Bureau of Labor Statistics (BLS), Department of Labor
39
+ **Website:** https://www.bls.gov/oes/
40
+
41
+ The OEWS program produces employment and wage estimates annually for over 800 occupations. These estimates are available for the nation as a whole, for individual states, and for metropolitan and nonmetropolitan areas.
42
+
43
+ ### Key Fields
44
+
45
+ | Field | Description |
46
+ |-------|-------------|
47
+ | `occ_title` | Occupation title |
48
+ | `area_title` | Geographic area name |
49
+ | `tot_emp` | Total employment |
50
+ | `a_mean` | Mean annual wage |
51
+ | `a_median` | Median annual wage |
52
+ | `h_mean` | Mean hourly wage |
53
+
54
+ ---
55
+
56
+ ## Features
57
+
58
+ - **Natural Language Queries**: Ask questions in plain English
59
+ - **SQL Transparency**: See the generated SQL for each query
60
+ - **Interactive Data Table**: Sort, filter, and export results
61
+ - **Miami University Theming**: Branded for ISA 401 course use
62
+
63
+ ---
64
+
65
+ ## Running Locally
66
+
67
+ **With R:**
68
+ ```r
69
+ # Install dependencies
70
+ renv::restore()
71
+
72
+ # Run the app
73
+ shiny::runApp('.', host = '0.0.0.0', port = 7860)
74
+ ```
75
+
76
+ **With Docker:**
77
+ ```bash
78
+ # Build the image
79
+ docker build -t oews-explorer .
80
+
81
+ # Run with OpenAI API key
82
+ docker run --rm -p 7860:7860 -e OPENAI_API_KEY=$OPENAI_API_KEY oews-explorer
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Required Environment Variable
88
+
89
+ This app requires an OpenAI API key to function:
90
+
91
+ ```bash
92
+ export OPENAI_API_KEY="your-api-key-here"
93
+ ```
94
+
95
+ On Hugging Face Spaces, set this as a secret in your Space settings.
96
+
97
+ ---
98
+
99
+ ## Technology Stack
100
+
101
+ - **[Shiny](https://shiny.posit.co/)** - Web application framework for R
102
+ - **[querychat](https://github.com/posit-dev/querychat)** - Natural language data querying
103
+ - **[bslib](https://rstudio.github.io/bslib/)** - Bootstrap theming for Shiny
104
+ - **[DT](https://rstudio.github.io/DT/)** - Interactive data tables
105
+
106
+ ---
107
+
108
+ ## Course Information
109
+
110
+ This application was developed for **ISA 401** at **Miami University** to help students explore and understand labor market data using modern AI-powered tools.
111
+
112
+ ---
113
+
114
+ ## Data Source
115
+
116
+ Bureau of Labor Statistics, U.S. Department of Labor. *Occupational Employment and Wage Statistics (OEWS), May 2024 Estimates.*
117
+ https://www.bls.gov/oes/
app.R ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ISA 401 OEWS Jobs Explorer
2
+ # A Shiny app for exploring U.S. Occupational Employment and Wage Statistics
3
+
4
+ library(shiny)
5
+ library(bslib)
6
+ library(querychat)
7
+ library(DT)
8
+ library(dplyr)
9
+ library(duckdb)
10
+
11
+ # Load preprocessed data
12
+ oews <- readRDS("data/oews.rds")
13
+
14
+ # Step 1: Create QueryChat object
15
+ client = ellmer::chat_openai(
16
+ model = "gpt-5-mini-2025-08-07",
17
+ credentials = function(){return(Sys.getenv("OPENAI_API_KEY"))}
18
+ )
19
+
20
+ qc = querychat::querychat(
21
+ oews,
22
+ client = client,
23
+ greeting = "Welcome to Our ISA 401 Assistant for Understanding the OEWS Dataset",
24
+ extra_instructions = "data/extra_instructions.md",
25
+ data_description = 'data/data_desc.md'
26
+ )
27
+
28
+ ## Based on the documentation:
29
+ # https://posit-dev.github.io/querychat/r/articles/build.html#programmatic-filtering
30
+
31
+ # Step 2: Add UI component
32
+ ui <- bslib::page_sidebar(
33
+ sidebar = qc$sidebar(),
34
+ bslib::card(
35
+ bslib::card_header("Data Table"),
36
+ DT::DTOutput("table")
37
+ ),
38
+ bslib::card(
39
+ fill = FALSE,
40
+ bslib::card_header("SQL Query"),
41
+ shiny::verbatimTextOutput("sql")
42
+ )
43
+ )
44
+
45
+ # Step 3: Use reactive values in server
46
+ server <- function(input, output, session) {
47
+ qc_vals <- qc$server()
48
+
49
+ output$table <- DT::renderDT({
50
+ DT::datatable(qc_vals$df(), fillContainer = TRUE)
51
+ })
52
+
53
+ output$sql <- shiny::renderText({
54
+ qc_vals$sql() %||% "SELECT * FROM oews"
55
+ })
56
+ }
57
+
58
+ shiny::shinyApp(ui, server)