-
Notifications
You must be signed in to change notification settings - Fork 44
31341 - Initial commit for pay-report - Streamlit (#2199) #2200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| name: Pay Report CD GCP | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - "pay-report/**" | ||
| workflow_dispatch: | ||
| inputs: | ||
| target: | ||
| description: "Deploy To" | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - dev | ||
| - test | ||
| - sandbox | ||
| - prod | ||
| redeploy: | ||
| description: "Redeploy Application" | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - "false" | ||
| - "true" | ||
| jobs: | ||
| pay-report-cd: | ||
| uses: bcgov/bcregistry-sre/.github/workflows/backend-cd.yaml@main | ||
| with: | ||
| target: ${{ inputs.target }} | ||
| app_name: "pay-report" | ||
| working_directory: "./pay-report" | ||
| redeploy: ${{ inputs.redeploy }} | ||
| secrets: | ||
| WORKLOAD_IDENTIFY_POOLS_PROVIDER: ${{ secrets.WORKLOAD_IDENTIFY_POOLS_PROVIDER }} | ||
| GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }} | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,114 @@ | ||||||||||||||||||||||||||||||||
| name: PAY REPORT CI | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||
| - main | ||||||||||||||||||||||||||||||||
| - release/* | ||||||||||||||||||||||||||||||||
| paths: | ||||||||||||||||||||||||||||||||
| - "pay-report/**" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| defaults: | ||||||||||||||||||||||||||||||||
| run: | ||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||
| working-directory: ./pay-report | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||
| setup-job: | ||||||||||||||||||||||||||||||||
| runs-on: ubuntu-24.04 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if: github.repository == 'bcgov/sbc-pay' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||
| - run: "true" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| linting: | ||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+26
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copilot AutofixAI about 2 months ago In general, the fix is to explicitly declare the The best way to fix this without changing existing behavior is to add a single permissions:
contents: readafter the
Suggested changeset
1
.github/workflows/pay-report-ci.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||
| needs: setup-job | ||||||||||||||||||||||||||||||||
| runs-on: ubuntu-24.04 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| strategy: | ||||||||||||||||||||||||||||||||
| matrix: | ||||||||||||||||||||||||||||||||
| python-version: [3.12] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||
| - name: Set up Python ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| uses: actions/setup-python@v5 | ||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||
| python-version: ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| - name: Install uv | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||||||||||||||||||||||||||||||||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| uv sync --extra dev | ||||||||||||||||||||||||||||||||
| - name: Lint with ruff | ||||||||||||||||||||||||||||||||
| id: ruff | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| uv run ruff check . | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| testing: | ||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+52
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copilot AutofixAI about 2 months ago In general, this issue is fixed by explicitly declaring a The best fix with no functional change is to add a single top‑level Concretely, in permissions:
contents: readbetween line 1 (
Suggested changeset
1
.github/workflows/pay-report-ci.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||
| needs: setup-job | ||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||
| PYTHONPATH: "./src" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| runs-on: ubuntu-24.04 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| strategy: | ||||||||||||||||||||||||||||||||
| matrix: | ||||||||||||||||||||||||||||||||
| python-version: [3.12] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| services: | ||||||||||||||||||||||||||||||||
| postgres: | ||||||||||||||||||||||||||||||||
| image: postgres:15.6 | ||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||
| POSTGRES_USER: postgres | ||||||||||||||||||||||||||||||||
| POSTGRES_PASSWORD: postgres | ||||||||||||||||||||||||||||||||
| POSTGRES_DB: pay-report-test | ||||||||||||||||||||||||||||||||
| ports: | ||||||||||||||||||||||||||||||||
| - 5432:5432 | ||||||||||||||||||||||||||||||||
| options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||
| - name: Set up Python ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| uses: actions/setup-python@v5 | ||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||
| python-version: ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| - name: Install uv | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||||||||||||||||||||||||||||||||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| uv sync --extra dev | ||||||||||||||||||||||||||||||||
| - name: Test with pytest | ||||||||||||||||||||||||||||||||
| id: test | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| uv run pytest | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| build-check: | ||||||||||||||||||||||||||||||||
|
Comment on lines
+53
to
+92
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copilot AutofixAI about 2 months ago To fix the problem, explicitly set a restrictive The best way to do this without changing functionality is to add a top‑level Concretely:
permissions:
contents: readbetween the
Suggested changeset
1
.github/workflows/pay-report-ci.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||
| needs: setup-job | ||||||||||||||||||||||||||||||||
| runs-on: ubuntu-24.04 | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| strategy: | ||||||||||||||||||||||||||||||||
| matrix: | ||||||||||||||||||||||||||||||||
| python-version: [3.12] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||
| - name: Set up Python ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| uses: actions/setup-python@v5 | ||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||
| python-version: ${{ matrix.python-version }} | ||||||||||||||||||||||||||||||||
| - name: Install uv | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||||||||||||||||||||||||||||||||
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | ||||||||||||||||||||||||||||||||
| - name: Build Docker image | ||||||||||||||||||||||||||||||||
| id: build | ||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||
| docker build -t pay-report:test . | ||||||||||||||||||||||||||||||||
|
Comment on lines
+93
to
+113
Check warningCode scanning / CodeQL Workflow does not contain permissions Medium
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Copilot AutofixAI about 2 months ago In general, the fix is to explicitly define Concretely, in permissions:
contents: readnear the top of the file (after
Suggested changeset
1
.github/workflows/pay-report-ci.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| __pycache__ | ||
| *.pyc | ||
| *.pyo | ||
| *.pyd | ||
| .Python | ||
| *.so | ||
| *.egg | ||
| *.egg-info | ||
| dist | ||
| build | ||
| .venv | ||
| venv | ||
| env | ||
| .env | ||
| .env.local | ||
| *.log | ||
| .git | ||
| .gitignore | ||
| README.md | ||
| .pytest_cache | ||
| .coverage | ||
| htmlcov | ||
| .DS_Store | ||
| *.swp | ||
| *.swo | ||
| *~ | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| .streamlit/secrets.toml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| [client] | ||
| showSidebarNavigation = false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| [auth] | ||
| redirect_uri = "http://localhost:8501/oauth2callback" | ||
| cookie_secret = "your-random-cookie-secret-here" | ||
| client_id = "your-client-id" | ||
| client_secret = "your-client-secret" | ||
| server_metadata_url = "http://localhost:8080/realms/your-realm/.well-known/openid-configuration" | ||
|
|
||
| [database] | ||
| # For regular PostgreSQL connections: | ||
| host = "localhost" | ||
| port = "5432" | ||
| name = "your_database_name" | ||
| username = "your_username" | ||
| password = "your_password" | ||
|
|
||
| # For Google Cloud SQL connections (optional): | ||
| # instance_connection = "project:region:instance" | ||
| # Uses IAM authentication - no password required | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| FROM python:3.13-slim | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| curl \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN pip install --no-cache-dir uv | ||
|
|
||
| COPY pyproject.toml ./ | ||
|
|
||
| RUN uv sync | ||
|
|
||
| COPY . . | ||
|
|
||
| # Convert .env to .streamlit/secrets.toml if it exists | ||
| RUN if [ -f .env ]; then \ | ||
| python3 scripts/env_to_toml.py .env .streamlit/secrets.toml; \ | ||
| fi | ||
|
|
||
| EXPOSE 8501 | ||
|
|
||
| HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1 | ||
|
|
||
| ENTRYPOINT ["uv", "run", "streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"] | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # Pay Team Report Dashboard | ||
|
|
||
| A Streamlit application with multiple pages that allows users to generate reports and download data as XLSX files. | ||
|
|
||
| ## Purpose | ||
|
|
||
| This application was created as a stopgap solution for PowerBI. It enables non-technical staff to generate and download reports independently, eliminating the need for developers to repeatedly run reports on demand. This isn't meant for complicated visuals or dashboards just a means to an end for access to data for business users. | ||
|
|
||
| ## Features | ||
|
|
||
| - **Streamlit Native Authentication**: User authentication using Streamlit's built-in OIDC support with Keycloak | ||
| - **Multi-page navigation**: Main dashboard and Analytics page | ||
| - **PostgreSQL integration**: Connect to your PostgreSQL database | ||
| - **XLSX download**: Export generated reports as XLSX files | ||
|
|
||
| ## Setup | ||
|
|
||
| ### 1. Install UV (if not already installed) | ||
|
|
||
| ```bash | ||
| curl -LsSf https://astral.sh/uv/install.sh | sh | ||
| ``` | ||
|
|
||
| Or using pip: | ||
| ```bash | ||
| pip install uv | ||
| ``` | ||
|
|
||
| ### 2. Install Dependencies | ||
|
|
||
| ```bash | ||
| uv sync | ||
| ``` | ||
|
|
||
| ### 3. Configure Streamlit Secrets | ||
|
|
||
| Create a `.streamlit/secrets.toml` file from the example: | ||
|
|
||
| ```bash | ||
| mkdir -p .streamlit | ||
| cp .streamlit/secrets.toml.example .streamlit/secrets.toml | ||
| ``` | ||
|
|
||
| Edit `.streamlit/secrets.toml` with your actual configuration values. See `.streamlit/secrets.toml.example` for the required structure. | ||
|
|
||
| ### 4. Run the Application | ||
|
|
||
| Using UV: | ||
| ```bash | ||
| uv run streamlit run app.py | ||
| ``` | ||
|
|
||
| Or using standard Python: | ||
|
|
||
| ```bash | ||
| streamlit run app.py | ||
| ``` | ||
|
|
||
| The application will open in your default web browser at `http://localhost:8501`. | ||
|
|
||
| ## Running Tests | ||
|
|
||
| Install test dependencies: | ||
|
|
||
| ```bash | ||
| uv sync --extra dev | ||
| ``` | ||
|
|
||
| Run the tests: | ||
|
|
||
| ```bash | ||
| uv run pytest | ||
| ``` | ||
|
|
||
| The tests verify that: | ||
| - `enforce_auth()` correctly handles authentication and role checks | ||
| - All pages in pages/*.py import from src (which enforces auth) | ||
|
|
||
| ## Linting | ||
|
|
||
| This project uses [ruff](https://docs.astral.sh/ruff/) for linting and code formatting. | ||
|
|
||
| Install dev dependencies: | ||
| ```bash | ||
| uv sync --extra dev | ||
| ``` | ||
|
|
||
| Run the linter: | ||
| ```bash | ||
| uv run ruff check . | ||
| ``` | ||
|
|
||
| Format code: | ||
| ```bash | ||
| uv run ruff format . | ||
| ``` | ||
|
|
||
| Check and format in one command: | ||
| ```bash | ||
| uv run ruff check . --fix | ||
| uv run ruff format . | ||
| ``` | ||
|
|
||
| ## Docker Setup | ||
|
|
||
| ### Build the Docker Image | ||
|
|
||
| ```bash | ||
| docker build -t pay-report . | ||
| ``` | ||
|
|
||
| ### Run with Docker | ||
|
|
||
| Mount your `.streamlit/secrets.toml` file: | ||
|
|
||
| ```bash | ||
| docker run -p 8501:8501 \ | ||
| -v $(pwd)/.streamlit/secrets.toml:/app/.streamlit/secrets.toml:ro \ | ||
| pay-report | ||
| ``` | ||
|
|
||
| **Note**: Make sure your `.streamlit/secrets.toml` file is configured with the correct values before running the container. | ||
|
|
||
| The application will be available at `http://localhost:8501`. | ||
|
|
||
| ## Notes | ||
|
|
||
| - Make sure your PostgreSQL database is running and accessible | ||
| - Make sure your Keycloak server is running and accessible | ||
| - The application requires authentication before accessing any pages | ||
| - Authentication is handled automatically using Streamlit's native authentication | ||
| - Each page maintains its own session state for report data | ||
|
|
||
|
|
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Copilot Autofix
AI about 2 months ago
In general, to fix this class of issue, you explicitly declare a
permissionsblock either at the root of the workflow (applying to all jobs without their ownpermissions) or on individual jobs. This constrains theGITHUB_TOKENto the least privileges needed, instead of relying on potentially broad repository defaults.For this specific workflow, the single best fix with minimal behavioral impact is to add a conservative
permissionsblock at the top level, after theon:block and beforejobs:. A common minimal baseline recommended by GitHub iscontents: read, which allows read access to repository contents while preventing unintended write operations. The reusable workflow you call can still specify additional or different permissions inside its own definition if needed; your workflow’s top-level block just ensures you are not accidentally inheriting over-permissive defaults.Concretely, in
.github/workflows/pay-report-cd.yml, add:on new lines between the existing
on:section (ending at line 26) and thejobs:section (line 27). No imports or additional definitions are required, as this is standard GitHub Actions YAML configuration.