# Looker Validator Implementation Guide
This guide walks you through setting up the Looker Validator tool for your CI/CD process.
## Step 1: Set Up a Dedicated Looker User
First, create a dedicated Looker user and API key with the appropriate permissions:
1. **Create a permission set**:
- Go to Admin > Roles
- Create a new permission set named "Validator User"
- Include these permissions:
- `access_data`
- `see_lookml_dashboards`
- `see_looks`
- `see_user_dashboards`
- `develop`
- `see_lookml`
- `see_sql`
2. **Create a role**:
- Go to Admin > Roles
- Create a new role named "Validator User"
- Add the "Validator User" permission set
- Select the model set(s) you want to validate
3. **Create the user**:
- Go to Admin > Users
- Create a new user (e.g., "validator@yourcompany.com")
- Assign the "Validator User" role
4. **Generate API credentials**:
- Edit the user
- Go to API3 Keys
- Click "New API Key"
- Save the client ID and client secret
## Step 2: Install Looker Validator
You can install the validator in your local environment or in your CI system:
```bash
pip install looker-validator
```
## Step 3: Configure the Validator
Create a configuration file `looker_validator_config.yaml`:
```yaml
# Looker API credentials
base_url: https://your-looker-instance.cloud.looker.com
client_id: YOUR_CLIENT_ID
client_secret: YOUR_CLIENT_SECRET
project: your_looker_project_name
# Optional global settings
log_dir: logs
# SQL validator settings
concurrency: 10
incremental: true
# Content validator settings
exclude_personal: true
incremental: true
# LookML validator settings
severity: warning
```
## Step 4: Test the Connection
Verify that you can connect to your Looker instance:
```bash
looker-validator connect --config-file looker_validator_config.yaml
```
You should see a success message with your Looker version.
## Step 5: Set Up GitHub Action
1. **Add secrets to your GitHub repository**:
- Go to your repository settings
- Click on Secrets > Actions
- Add the following secrets:
- `LOOKER_BASE_URL`: Your Looker instance URL
- `LOOKER_CLIENT_ID`: The API client ID
- `LOOKER_CLIENT_SECRET`: The API client secret
2. **Create workflow file**:
Create a file at `.github/workflows/looker-validation.yml`:
```yaml
name: Looker Validation
on:
pull_request:
branches: [ main, master, dev ]
paths:
- '**.view.lkml'
- '**.model.lkml'
- '**.explore.lkml'
- '**.dashboard.lookml'
- '**manifest.lkml'
jobs:
validate:
name: Validate Looker Project
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install looker-validator
run: |
python -m pip install --upgrade pip
pip install looker-validator
- name: Test connection
run: |
looker-validator connect \
--base-url ${{ secrets.LOOKER_BASE_URL }} \
--client-id ${{ secrets.LOOKER_CLIENT_ID }} \
--client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \
--project ${{ github.event.repository.name }}
- name: Run LookML validation
run: |
looker-validator lookml \
--base-url ${{ secrets.LOOKER_BASE_URL }} \
--client-id ${{ secrets.LOOKER_CLIENT_ID }} \
--client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \
--project ${{ github.event.repository.name }} \
--branch ${{ github.head_ref }}
- name: Run SQL validation
run: |
looker-validator sql \
--base-url ${{ secrets.LOOKER_BASE_URL }} \
--client-id ${{ secrets.LOOKER_CLIENT_ID }} \
--client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \
--project ${{ github.event.repository.name }} \
--branch ${{ github.head_ref }} \
--incremental
- name: Run Content validation
run: |
looker-validator content \
--base-url ${{ secrets.LOOKER_BASE_URL }} \
--client-id ${{ secrets.LOOKER_CLIENT_ID }} \
--client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \
--project ${{ github.event.repository.name }} \
--branch ${{ github.head_ref }} \
--incremental \
--exclude-personal
- name: Run Assert validation
run: |
looker-validator assert \
--base-url ${{ secrets.LOOKER_BASE_URL }} \
--client-id ${{ secrets.LOOKER_CLIENT_ID }} \
--client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \
--project ${{ github.event.repository.name }} \
--branch ${{ github.head_ref }}
- name: Upload logs
if: always()
uses: actions/upload-artifact@v3
with:
name: validation-logs
path: logs/
```
## Step 6: Customize Your Validation Process
Depending on your needs, you may want to customize your validation:
### For Large Projects
If you have a large Looker project, consider:
1. **Selecting specific models/explores**:
```bash
looker-validator sql --explores model_a/* model_b/explore_c
```
2. **Increasing concurrency**:
```bash
looker-validator sql --concurrency 20
```
3. **Running validators in sequence** to avoid branch conflicts
### For Faster Validations
To speed up validation:
1. **Use incremental mode**:
```bash
looker-validator sql --incremental
```
2. **Use fail-fast for SQL validation**:
```bash
looker-validator sql --fail-fast
```
3. **Exclude specific explores/folders**:
```bash
looker-validator content --explores -model_a/explore_b --folders -33
```
## Step 7: Handling Errors
When validation fails, the GitHub Action will fail with a non-zero exit code. The logs will contain detailed information about the failures.
You can view the logs in two ways:
1. **GitHub Actions logs**: View the output directly in the GitHub Actions interface
2. **Downloaded artifacts**: Download the logs artifact for detailed error information
## Best Practices
1. **Ignore dimensions that validly fail**:
```lookml
dimension: complex_calculation {
sql: ${TABLE}.value ;;
tags: ["spectacles: ignore"]
}
```
2. **Use incremental validation** to only show new errors
3. **Run all validators** for comprehensive testing
4. **Consider test concurrency** in CI environments
5. **Set up branch protection rules** to prevent merging PRs with validation failures
## Troubleshooting
### Common Issues
1. **Authentication Failures**:
- Verify API credentials
- Check API user permissions
2. **Branch Conflicts**:
- Use separate API users for concurrent validations
- Add concurrency limits to your GitHub workflow
3. **SQL Errors**:
- Check the SQL logs for specific error details
- Ignore dimensions that validly fail
4. **Content Errors**:
- Use `--exclude-personal` to focus on shared content
- Check for missing fields referenced by dashboards
### Getting Help
If you encounter issues:
1. Run validators with `--verbose` for detailed logs
2. Check log files in the `logs` directory
3. Review the GitHub Action output
Raw data
{
"_id": null,
"home_page": "https://github.com/stankovicst/looker-validator",
"name": "looker-validator",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "looker, lookml, validation, ci, continuous integration, testing",
"author": "Stevan Stankovic",
"author_email": "stankovicst@mediamarktsaturn.com",
"download_url": "https://files.pythonhosted.org/packages/1c/4c/fc0e776a88d6f494cb401528ff3ec3ef5bb068de524183be6a32646386ac/looker_validator-0.4.0.tar.gz",
"platform": null,
"description": "# Looker Validator Implementation Guide\n\nThis guide walks you through setting up the Looker Validator tool for your CI/CD process. \n\n## Step 1: Set Up a Dedicated Looker User\n\nFirst, create a dedicated Looker user and API key with the appropriate permissions:\n\n1. **Create a permission set**:\n - Go to Admin > Roles\n - Create a new permission set named \"Validator User\"\n - Include these permissions:\n - `access_data`\n - `see_lookml_dashboards`\n - `see_looks`\n - `see_user_dashboards`\n - `develop`\n - `see_lookml`\n - `see_sql`\n\n2. **Create a role**:\n - Go to Admin > Roles\n - Create a new role named \"Validator User\"\n - Add the \"Validator User\" permission set\n - Select the model set(s) you want to validate\n\n3. **Create the user**:\n - Go to Admin > Users\n - Create a new user (e.g., \"validator@yourcompany.com\")\n - Assign the \"Validator User\" role\n\n4. **Generate API credentials**:\n - Edit the user\n - Go to API3 Keys\n - Click \"New API Key\"\n - Save the client ID and client secret\n\n## Step 2: Install Looker Validator\n\nYou can install the validator in your local environment or in your CI system:\n\n```bash\npip install looker-validator\n```\n\n## Step 3: Configure the Validator\n\nCreate a configuration file `looker_validator_config.yaml`:\n\n```yaml\n# Looker API credentials\nbase_url: https://your-looker-instance.cloud.looker.com\nclient_id: YOUR_CLIENT_ID\nclient_secret: YOUR_CLIENT_SECRET\nproject: your_looker_project_name\n\n# Optional global settings\nlog_dir: logs\n\n# SQL validator settings\nconcurrency: 10\nincremental: true\n\n# Content validator settings\nexclude_personal: true\nincremental: true\n\n# LookML validator settings\nseverity: warning\n```\n\n## Step 4: Test the Connection\n\nVerify that you can connect to your Looker instance:\n\n```bash\nlooker-validator connect --config-file looker_validator_config.yaml\n```\n\nYou should see a success message with your Looker version.\n\n## Step 5: Set Up GitHub Action\n\n1. **Add secrets to your GitHub repository**:\n - Go to your repository settings\n - Click on Secrets > Actions\n - Add the following secrets:\n - `LOOKER_BASE_URL`: Your Looker instance URL\n - `LOOKER_CLIENT_ID`: The API client ID\n - `LOOKER_CLIENT_SECRET`: The API client secret\n\n2. **Create workflow file**:\n \n Create a file at `.github/workflows/looker-validation.yml`:\n\n ```yaml\n name: Looker Validation\n\n on:\n pull_request:\n branches: [ main, master, dev ]\n paths:\n - '**.view.lkml'\n - '**.model.lkml'\n - '**.explore.lkml'\n - '**.dashboard.lookml'\n - '**manifest.lkml'\n\n jobs:\n validate:\n name: Validate Looker Project\n runs-on: ubuntu-latest\n \n steps:\n - name: Checkout code\n uses: actions/checkout@v3\n \n - name: Set up Python\n uses: actions/setup-python@v4\n with:\n python-version: '3.9'\n \n - name: Install looker-validator\n run: |\n python -m pip install --upgrade pip\n pip install looker-validator\n \n - name: Test connection\n run: |\n looker-validator connect \\\n --base-url ${{ secrets.LOOKER_BASE_URL }} \\\n --client-id ${{ secrets.LOOKER_CLIENT_ID }} \\\n --client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \\\n --project ${{ github.event.repository.name }}\n \n - name: Run LookML validation\n run: |\n looker-validator lookml \\\n --base-url ${{ secrets.LOOKER_BASE_URL }} \\\n --client-id ${{ secrets.LOOKER_CLIENT_ID }} \\\n --client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \\\n --project ${{ github.event.repository.name }} \\\n --branch ${{ github.head_ref }}\n \n - name: Run SQL validation\n run: |\n looker-validator sql \\\n --base-url ${{ secrets.LOOKER_BASE_URL }} \\\n --client-id ${{ secrets.LOOKER_CLIENT_ID }} \\\n --client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \\\n --project ${{ github.event.repository.name }} \\\n --branch ${{ github.head_ref }} \\\n --incremental\n \n - name: Run Content validation\n run: |\n looker-validator content \\\n --base-url ${{ secrets.LOOKER_BASE_URL }} \\\n --client-id ${{ secrets.LOOKER_CLIENT_ID }} \\\n --client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \\\n --project ${{ github.event.repository.name }} \\\n --branch ${{ github.head_ref }} \\\n --incremental \\\n --exclude-personal\n \n - name: Run Assert validation\n run: |\n looker-validator assert \\\n --base-url ${{ secrets.LOOKER_BASE_URL }} \\\n --client-id ${{ secrets.LOOKER_CLIENT_ID }} \\\n --client-secret ${{ secrets.LOOKER_CLIENT_SECRET }} \\\n --project ${{ github.event.repository.name }} \\\n --branch ${{ github.head_ref }}\n \n - name: Upload logs\n if: always()\n uses: actions/upload-artifact@v3\n with:\n name: validation-logs\n path: logs/\n ```\n\n## Step 6: Customize Your Validation Process\n\nDepending on your needs, you may want to customize your validation:\n\n### For Large Projects\n\nIf you have a large Looker project, consider:\n\n1. **Selecting specific models/explores**:\n ```bash\n looker-validator sql --explores model_a/* model_b/explore_c\n ```\n\n2. **Increasing concurrency**:\n ```bash\n looker-validator sql --concurrency 20\n ```\n\n3. **Running validators in sequence** to avoid branch conflicts\n\n### For Faster Validations\n\nTo speed up validation:\n\n1. **Use incremental mode**:\n ```bash\n looker-validator sql --incremental\n ```\n\n2. **Use fail-fast for SQL validation**:\n ```bash\n looker-validator sql --fail-fast\n ```\n\n3. **Exclude specific explores/folders**:\n ```bash\n looker-validator content --explores -model_a/explore_b --folders -33\n ```\n\n## Step 7: Handling Errors\n\nWhen validation fails, the GitHub Action will fail with a non-zero exit code. The logs will contain detailed information about the failures.\n\nYou can view the logs in two ways:\n\n1. **GitHub Actions logs**: View the output directly in the GitHub Actions interface\n\n2. **Downloaded artifacts**: Download the logs artifact for detailed error information\n\n## Best Practices\n\n1. **Ignore dimensions that validly fail**:\n ```lookml\n dimension: complex_calculation {\n sql: ${TABLE}.value ;;\n tags: [\"spectacles: ignore\"]\n }\n ```\n\n2. **Use incremental validation** to only show new errors\n\n3. **Run all validators** for comprehensive testing\n\n4. **Consider test concurrency** in CI environments\n\n5. **Set up branch protection rules** to prevent merging PRs with validation failures\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Authentication Failures**:\n - Verify API credentials\n - Check API user permissions\n\n2. **Branch Conflicts**:\n - Use separate API users for concurrent validations\n - Add concurrency limits to your GitHub workflow\n\n3. **SQL Errors**:\n - Check the SQL logs for specific error details\n - Ignore dimensions that validly fail\n\n4. **Content Errors**:\n - Use `--exclude-personal` to focus on shared content\n - Check for missing fields referenced by dashboards\n\n### Getting Help\n\nIf you encounter issues:\n\n1. Run validators with `--verbose` for detailed logs\n2. Check log files in the `logs` directory\n3. Review the GitHub Action output\n",
"bugtrack_url": null,
"license": null,
"summary": "A continuous integration tool for Looker and LookML validation",
"version": "0.4.0",
"project_urls": {
"Bug Tracker": "https://github.com/stankovicst/looker-validator/issues",
"Documentation": "https://github.com/stankovicst/looker-validator#readme",
"Homepage": "https://github.com/stankovicst/looker-validator",
"Source Code": "https://github.com/stankovicst/looker-validator"
},
"split_keywords": [
"looker",
" lookml",
" validation",
" ci",
" continuous integration",
" testing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e6ede7af218260e465040f0a59912da553b1c3ed1b32e9e80f1662bf47342132",
"md5": "cf95cf1798f08a6921a6ccd8e4e16a68",
"sha256": "df52bfd8f04c55bb813c58d938dd07b52bb7e68e92779137f6a8c8787dd9c817"
},
"downloads": -1,
"filename": "looker_validator-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cf95cf1798f08a6921a6ccd8e4e16a68",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 62134,
"upload_time": "2025-08-18T16:51:51",
"upload_time_iso_8601": "2025-08-18T16:51:51.326055Z",
"url": "https://files.pythonhosted.org/packages/e6/ed/e7af218260e465040f0a59912da553b1c3ed1b32e9e80f1662bf47342132/looker_validator-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1c4cfc0e776a88d6f494cb401528ff3ec3ef5bb068de524183be6a32646386ac",
"md5": "b4b3da5ac0864905b40bff36b813d347",
"sha256": "8f227780748602e97862a50076bcf771dad375c7b3950f1ea4166698f8292e66"
},
"downloads": -1,
"filename": "looker_validator-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "b4b3da5ac0864905b40bff36b813d347",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 54722,
"upload_time": "2025-08-18T16:51:52",
"upload_time_iso_8601": "2025-08-18T16:51:52.975631Z",
"url": "https://files.pythonhosted.org/packages/1c/4c/fc0e776a88d6f494cb401528ff3ec3ef5bb068de524183be6a32646386ac/looker_validator-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-18 16:51:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "stankovicst",
"github_project": "looker-validator",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "looker-validator"
}