squirrels 0.4.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of squirrels might be problematic. Click here for more details.

Files changed (125) hide show
  1. dateutils/__init__.py +6 -0
  2. dateutils/_enums.py +25 -0
  3. squirrels/dateutils.py → dateutils/_implementation.py +58 -111
  4. dateutils/types.py +6 -0
  5. squirrels/__init__.py +13 -11
  6. squirrels/_api_routes/__init__.py +5 -0
  7. squirrels/_api_routes/auth.py +271 -0
  8. squirrels/_api_routes/base.py +165 -0
  9. squirrels/_api_routes/dashboards.py +150 -0
  10. squirrels/_api_routes/data_management.py +145 -0
  11. squirrels/_api_routes/datasets.py +257 -0
  12. squirrels/_api_routes/oauth2.py +298 -0
  13. squirrels/_api_routes/project.py +252 -0
  14. squirrels/_api_server.py +256 -450
  15. squirrels/_arguments/__init__.py +0 -0
  16. squirrels/_arguments/init_time_args.py +108 -0
  17. squirrels/_arguments/run_time_args.py +147 -0
  18. squirrels/_auth.py +960 -0
  19. squirrels/_command_line.py +126 -45
  20. squirrels/_compile_prompts.py +147 -0
  21. squirrels/_connection_set.py +48 -26
  22. squirrels/_constants.py +68 -38
  23. squirrels/_dashboards.py +160 -0
  24. squirrels/_data_sources.py +570 -0
  25. squirrels/_dataset_types.py +84 -0
  26. squirrels/_exceptions.py +29 -0
  27. squirrels/_initializer.py +177 -80
  28. squirrels/_logging.py +115 -0
  29. squirrels/_manifest.py +208 -79
  30. squirrels/_model_builder.py +69 -0
  31. squirrels/_model_configs.py +74 -0
  32. squirrels/_model_queries.py +52 -0
  33. squirrels/_models.py +926 -367
  34. squirrels/_package_data/base_project/.env +42 -0
  35. squirrels/_package_data/base_project/.env.example +42 -0
  36. squirrels/_package_data/base_project/assets/expenses.db +0 -0
  37. squirrels/_package_data/base_project/connections.yml +16 -0
  38. squirrels/_package_data/base_project/dashboards/dashboard_example.py +34 -0
  39. squirrels/_package_data/base_project/dashboards/dashboard_example.yml +22 -0
  40. squirrels/{package_data → _package_data}/base_project/docker/.dockerignore +5 -2
  41. squirrels/{package_data → _package_data}/base_project/docker/Dockerfile +3 -3
  42. squirrels/{package_data → _package_data}/base_project/docker/compose.yml +1 -1
  43. squirrels/_package_data/base_project/duckdb_init.sql +10 -0
  44. squirrels/{package_data/base_project/.gitignore → _package_data/base_project/gitignore} +3 -2
  45. squirrels/_package_data/base_project/macros/macros_example.sql +17 -0
  46. squirrels/_package_data/base_project/models/builds/build_example.py +26 -0
  47. squirrels/_package_data/base_project/models/builds/build_example.sql +16 -0
  48. squirrels/_package_data/base_project/models/builds/build_example.yml +57 -0
  49. squirrels/_package_data/base_project/models/dbviews/dbview_example.sql +12 -0
  50. squirrels/_package_data/base_project/models/dbviews/dbview_example.yml +26 -0
  51. squirrels/_package_data/base_project/models/federates/federate_example.py +37 -0
  52. squirrels/_package_data/base_project/models/federates/federate_example.sql +19 -0
  53. squirrels/_package_data/base_project/models/federates/federate_example.yml +65 -0
  54. squirrels/_package_data/base_project/models/sources.yml +38 -0
  55. squirrels/{package_data → _package_data}/base_project/parameters.yml +56 -40
  56. squirrels/_package_data/base_project/pyconfigs/connections.py +14 -0
  57. squirrels/{package_data → _package_data}/base_project/pyconfigs/context.py +21 -40
  58. squirrels/_package_data/base_project/pyconfigs/parameters.py +141 -0
  59. squirrels/_package_data/base_project/pyconfigs/user.py +44 -0
  60. squirrels/_package_data/base_project/seeds/seed_categories.yml +15 -0
  61. squirrels/_package_data/base_project/seeds/seed_subcategories.csv +15 -0
  62. squirrels/_package_data/base_project/seeds/seed_subcategories.yml +21 -0
  63. squirrels/_package_data/base_project/squirrels.yml.j2 +61 -0
  64. squirrels/_package_data/templates/dataset_results.html +112 -0
  65. squirrels/_package_data/templates/oauth_login.html +271 -0
  66. squirrels/_package_data/templates/squirrels_studio.html +20 -0
  67. squirrels/_package_loader.py +8 -4
  68. squirrels/_parameter_configs.py +104 -103
  69. squirrels/_parameter_options.py +348 -0
  70. squirrels/_parameter_sets.py +57 -47
  71. squirrels/_parameters.py +1664 -0
  72. squirrels/_project.py +721 -0
  73. squirrels/_py_module.py +7 -5
  74. squirrels/_schemas/__init__.py +0 -0
  75. squirrels/_schemas/auth_models.py +167 -0
  76. squirrels/_schemas/query_param_models.py +75 -0
  77. squirrels/{_api_response_models.py → _schemas/response_models.py} +126 -47
  78. squirrels/_seeds.py +35 -16
  79. squirrels/_sources.py +110 -0
  80. squirrels/_utils.py +248 -73
  81. squirrels/_version.py +1 -1
  82. squirrels/arguments.py +7 -0
  83. squirrels/auth.py +4 -0
  84. squirrels/connections.py +3 -0
  85. squirrels/dashboards.py +2 -81
  86. squirrels/data_sources.py +14 -631
  87. squirrels/parameter_options.py +13 -348
  88. squirrels/parameters.py +14 -1266
  89. squirrels/types.py +16 -0
  90. squirrels-0.5.0.dist-info/METADATA +113 -0
  91. squirrels-0.5.0.dist-info/RECORD +97 -0
  92. {squirrels-0.4.0.dist-info → squirrels-0.5.0.dist-info}/WHEEL +1 -1
  93. squirrels-0.5.0.dist-info/entry_points.txt +3 -0
  94. {squirrels-0.4.0.dist-info → squirrels-0.5.0.dist-info/licenses}/LICENSE +1 -1
  95. squirrels/_authenticator.py +0 -85
  96. squirrels/_dashboards_io.py +0 -61
  97. squirrels/_environcfg.py +0 -84
  98. squirrels/arguments/init_time_args.py +0 -40
  99. squirrels/arguments/run_time_args.py +0 -208
  100. squirrels/package_data/assets/favicon.ico +0 -0
  101. squirrels/package_data/assets/index.css +0 -1
  102. squirrels/package_data/assets/index.js +0 -58
  103. squirrels/package_data/base_project/assets/expenses.db +0 -0
  104. squirrels/package_data/base_project/connections.yml +0 -7
  105. squirrels/package_data/base_project/dashboards/dashboard_example.py +0 -32
  106. squirrels/package_data/base_project/dashboards.yml +0 -10
  107. squirrels/package_data/base_project/env.yml +0 -29
  108. squirrels/package_data/base_project/models/dbviews/dbview_example.py +0 -47
  109. squirrels/package_data/base_project/models/dbviews/dbview_example.sql +0 -22
  110. squirrels/package_data/base_project/models/federates/federate_example.py +0 -21
  111. squirrels/package_data/base_project/models/federates/federate_example.sql +0 -3
  112. squirrels/package_data/base_project/pyconfigs/auth.py +0 -45
  113. squirrels/package_data/base_project/pyconfigs/connections.py +0 -19
  114. squirrels/package_data/base_project/pyconfigs/parameters.py +0 -95
  115. squirrels/package_data/base_project/seeds/seed_subcategories.csv +0 -15
  116. squirrels/package_data/base_project/squirrels.yml.j2 +0 -94
  117. squirrels/package_data/templates/index.html +0 -18
  118. squirrels/project.py +0 -378
  119. squirrels/user_base.py +0 -55
  120. squirrels-0.4.0.dist-info/METADATA +0 -117
  121. squirrels-0.4.0.dist-info/RECORD +0 -60
  122. squirrels-0.4.0.dist-info/entry_points.txt +0 -4
  123. /squirrels/{package_data → _package_data}/base_project/assets/weather.db +0 -0
  124. /squirrels/{package_data → _package_data}/base_project/seeds/seed_categories.csv +0 -0
  125. /squirrels/{package_data → _package_data}/base_project/tmp/.gitignore +0 -0
@@ -0,0 +1,42 @@
1
+ # Custom environment variables
2
+ SQLITE_URI="sqlite:///{project_path}/assets/expenses.db"
3
+
4
+ # Secrets used by the Squirrels framework that are NOT SAFE TO INCLUDE IN VERSION CONTROL
5
+ # Required if your project uses authentication. Otherwise, optional.
6
+ SQRL_SECRET__KEY="{{ random_secret_key }}"
7
+ SQRL_SECRET__ADMIN_PASSWORD="{{ random_admin_password }}"
8
+
9
+ # Optional variables used by the Squirrels framework that are safe to include in version control if desired
10
+ # (default values are shown below)
11
+ SQRL_AUTH__DB_FILE_PATH="{project_path}/target/auth.sqlite"
12
+ SQRL_AUTH__TOKEN_EXPIRE_MINUTES="30"
13
+ SQRL_AUTH__ALLOWED_ORIGINS_FOR_COOKIES="https://squirrels-analytics.github.io"
14
+
15
+ SQRL_PARAMETERS__CACHE_SIZE="1024"
16
+ SQRL_PARAMETERS__CACHE_TTL_MINUTES="60"
17
+ SQRL_PARAMETERS__DATASOURCE_REFRESH_MINUTES="60"
18
+
19
+ SQRL_DATASETS__CACHE_SIZE="128"
20
+ SQRL_DATASETS__CACHE_TTL_MINUTES="60"
21
+ SQRL_DATASETS__MAX_ROWS_FOR_AI="100"
22
+
23
+ SQRL_DASHBOARDS__CACHE_SIZE="128"
24
+ SQRL_DASHBOARDS__CACHE_TTL_MINUTES="60"
25
+
26
+ SQRL_PERMISSIONS__ELEVATED_ACCESS_LEVEL="admin" # one of "admin", "member", "guest"
27
+
28
+ SQRL_SEEDS__INFER_SCHEMA="true"
29
+ SQRL_SEEDS__NA_VALUES=["NA"] # must be a JSON list
30
+
31
+ SQRL_CONNECTIONS__DEFAULT_NAME_USED="default"
32
+
33
+ SQRL_VDL__CATALOG_DB_PATH="ducklake:{project_path}/target/vdl_catalog.duckdb"
34
+ SQRL_VDL__DATA_PATH="{project_path}/target/vdl_data/"
35
+
36
+ SQRL_STUDIO__BASE_URL="https://squirrels-analytics.github.io/squirrels-studio-v1"
37
+
38
+ SQRL_LOGGING__LOG_LEVEL="INFO" # one of "DEBUG", "INFO", "WARNING"
39
+ SQRL_LOGGING__LOG_FORMAT="text"
40
+ SQRL_LOGGING__LOG_TO_FILE="false"
41
+ SQRL_LOGGING__LOG_FILE_SIZE_MB="50"
42
+ SQRL_LOGGING__LOG_FILE_BACKUP_COUNT="1"
@@ -0,0 +1,42 @@
1
+ # Custom environment variables
2
+ SQLITE_URI="sqlite:///{project_path}/assets/expenses.db"
3
+
4
+ # Secrets used by the Squirrels framework that are NOT SAFE TO INCLUDE IN VERSION CONTROL
5
+ # Required if your project uses authentication. Otherwise, optional.
6
+ SQRL_SECRET__KEY="" # a random 32 byte hex string - one way to generate this is by running "openssl rand -hex 32" in bash
7
+ SQRL_SECRET__ADMIN_PASSWORD=""
8
+
9
+ # Optional variables used by the Squirrels framework that are safe to include in version control if desired
10
+ # (default values are shown below)
11
+ SQRL_AUTH__DB_FILE_PATH="target/auth.sqlite"
12
+ SQRL_AUTH__TOKEN_EXPIRE_MINUTES="30"
13
+ SQRL_AUTH__ALLOWED_ORIGINS_FOR_COOKIES="https://squirrels-analytics.github.io"
14
+
15
+ SQRL_PARAMETERS__CACHE_SIZE="1024"
16
+ SQRL_PARAMETERS__CACHE_TTL_MINUTES="60"
17
+ SQRL_PARAMETERS__DATASOURCE_REFRESH_MINUTES="60"
18
+
19
+ SQRL_DATASETS__CACHE_SIZE="128"
20
+ SQRL_DATASETS__CACHE_TTL_MINUTES="60"
21
+ SQRL_DATASETS__MAX_ROWS_FOR_AI="100"
22
+
23
+ SQRL_DASHBOARDS__CACHE_SIZE="128"
24
+ SQRL_DASHBOARDS__CACHE_TTL_MINUTES="60"
25
+
26
+ SQRL_PERMISSIONS__ELEVATED_ACCESS_LEVEL="admin" # one of "admin", "member", "guest"
27
+
28
+ SQRL_SEEDS__INFER_SCHEMA="true"
29
+ SQRL_SEEDS__NA_VALUES=["NA"] # must be a JSON list
30
+
31
+ SQRL_CONNECTIONS__DEFAULT_NAME_USED="default"
32
+
33
+ SQRL_VDL__CATALOG_DB_PATH="ducklake:{project_path}/target/vdl_catalog.duckdb"
34
+ SQRL_VDL__DATA_PATH="{project_path}/target/vdl_data/"
35
+
36
+ SQRL_STUDIO__BASE_URL="https://squirrels-analytics.github.io/squirrels-studio-v1"
37
+
38
+ SQRL_LOGGING__LOG_LEVEL="INFO" # one of "DEBUG", "INFO", "WARNING"
39
+ SQRL_LOGGING__LOG_FORMAT="text"
40
+ SQRL_LOGGING__LOG_TO_FILE="false"
41
+ SQRL_LOGGING__LOG_FILE_SIZE_MB="50"
42
+ SQRL_LOGGING__LOG_FILE_BACKUP_COUNT="1"
@@ -0,0 +1,16 @@
1
+ ## Connection URIs are usually in format "dialect://username:password@host:port/database" for database connections
2
+ ## However, subtle differences exist depending on the "type" specified. For example, sqlite URIs are slightly different.
3
+ ## sqlalchemy: sqlite:///{project_path}/relative/path/to/database.db
4
+ ## connectorx/adbc: sqlite://{project_path}/relative/path/to/database.db (adbc URI format matches connectorx)
5
+ ## duckdb: sqlite:{project_path}/relative/path/to/database.db
6
+ ## Refer to specific documentation for supported databases by type (with URI examples):
7
+ ## sqlalchemy: https://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls
8
+ ## connectorx: https://sfu-db.github.io/connector-x/databases.html
9
+ ## adbc: https://arrow.apache.org/adbc/ (see connectorx documentation for URI examples)
10
+ connections:
11
+ - name: default
12
+ label: SQLite Expenses Database
13
+ type: sqlalchemy ## one of: sqlalchemy, connectorx, adbc, or duckdb
14
+ uri: {{ env_vars.SQLITE_URI }} ## using Jinja to substitute environment variables
15
+
16
+
@@ -0,0 +1,34 @@
1
+ from squirrels import arguments as args, dashboards as d
2
+ from matplotlib import pyplot as plt, figure as f, axes as a
3
+
4
+
5
+ async def main(sqrl: args.DashboardArgs) -> d.PngDashboard:
6
+ spending_by_month_df = await sqrl.dataset("federate_dataset_example", fixed_parameters={"group_by": "month"})
7
+ spending_by_subcategory_df = await sqrl.dataset("federate_dataset_example", fixed_parameters={"group_by": "subcat"})
8
+
9
+ # Create a figure with two subplots
10
+ fig, (ax0, ax1) = plt.subplots(2, 1, figsize=(8, 8), height_ratios=(1, 2))
11
+ fig: f.Figure; ax0: a.Axes; ax1: a.Axes
12
+ fig.tight_layout(pad=4, h_pad=6)
13
+
14
+ # Create a bar chart of spending by month
15
+
16
+ # Convert to pandas and ensure total_amount is numeric
17
+ spending_by_month_pandas = spending_by_month_df.sort("month").to_pandas()
18
+ spending_by_month_pandas["total_amount"] = spending_by_month_pandas["total_amount"].astype(float)
19
+
20
+ spending_by_month_pandas.plot(x="month", y="total_amount", ax=ax0)
21
+ ax0.set_title("Spending by Month")
22
+
23
+ # Create a pie chart of spending by subcategory
24
+
25
+ # Convert to pandas and ensure total_amount is numeric
26
+ subcategory_pandas = spending_by_subcategory_df.sort("total_amount", descending=True).to_pandas()
27
+ subcategory_pandas["total_amount"] = subcategory_pandas["total_amount"].astype(float)
28
+ subcategory_pandas.set_index("subcategory", inplace=True)
29
+
30
+ autopct = lambda pct: ('%.1f%%' % pct) if pct > 6 else ''
31
+ subcategory_pandas.plot(y="total_amount", kind='pie', ax=ax1, autopct=autopct, legend=False, ylabel="")
32
+ ax1.set_title("Spending by Subcategory")
33
+
34
+ return d.PngDashboard(fig)
@@ -0,0 +1,22 @@
1
+ label: Dashboard Example
2
+
3
+ description: This is an example dashboard
4
+
5
+ scope: protected
6
+
7
+ format: png
8
+
9
+ parameters:
10
+ - date_range
11
+ - category
12
+
13
+ depends_on:
14
+ - name: dataset_example_month
15
+ dataset: federate_dataset_example
16
+ fixed_parameters:
17
+ - group_by: month (Month)
18
+
19
+ - name: dataset_example_subcategory
20
+ dataset: federate_dataset_example
21
+ fixed_parameters:
22
+ - group_by: subcat (Subcategory)
@@ -2,12 +2,15 @@
2
2
 
3
3
  # common virtual environment names
4
4
  .venv/
5
+ venv/
5
6
 
6
7
  # squirrels files to ignore
7
- env.yml
8
+ .env
9
+ .env.local
10
+ duckdb_init.sql
11
+ logs/
8
12
  target/
9
13
  sqrl_packages/
10
14
 
11
15
  # additional files for docker to ignore
12
- Dockerfile
13
16
  .git/
@@ -8,9 +8,9 @@ COPY . .
8
8
  # "sqrl deps" command if there are packages defined in "squirrels.yml"
9
9
  RUN apt-get update && apt-get install -y git
10
10
 
11
- RUN pip install --no-cache-dir -r requirements-lock.txt
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
12
 
13
- RUN squirrels deps
13
+ RUN sqrl deps
14
14
 
15
15
  EXPOSE 4465
16
- CMD ["squirrels", "run", "--host", "0.0.0.0", "--port", "4465"]
16
+ CMD ["sqrl", "run", "--build", "--host", "0.0.0.0", "--port", "4465"]
@@ -4,4 +4,4 @@ services:
4
4
  ports:
5
5
  - "4465:4465"
6
6
  volumes:
7
- - ./env.yml:/app/env.yml
7
+ - ./.env:/app/.env
@@ -0,0 +1,10 @@
1
+ -- SQL statements that run at the start of every DuckDB session
2
+ -- If the VDL catalog path is provided, the project will ATTACH it as 'vdl' (READ_ONLY)
3
+
4
+ -- Example:
5
+
6
+ -- SET threads = 4;
7
+
8
+ -- SET temp_directory = '/path/to/tmp/';
9
+
10
+ -- CREATE SECRET (TYPE S3, PROVIDER CREDENTIAL_CHAIN);
@@ -1,12 +1,13 @@
1
1
  **/__pycache__/
2
2
 
3
3
  # common virtual environment names
4
- .env/
5
4
  .venv/
6
5
  venv/
7
6
 
8
7
  # squirrels files to ignore
9
- env.yml
8
+ .env
9
+ .env.local
10
+ duckdb_init.sql
10
11
  logs/
11
12
  target/
12
13
  sqrl_packages/
@@ -0,0 +1,17 @@
1
+ {%- macro date_and_amount_filters(use_from_range) -%}
2
+ {%- if use_from_range -%}
3
+
4
+ date >= {{ ctx.start_date_from_range | quote }}
5
+ AND date <= {{ ctx.end_date_from_range | quote }}
6
+ AND amount >= {{ ctx.min_amount_from_range }}
7
+ AND amount <= {{ ctx.max_amount_from_range }}
8
+
9
+ {%- else -%}
10
+
11
+ date >= {{ ctx.start_date | quote }}
12
+ AND date <= {{ ctx.end_date | quote }}
13
+ AND amount >= {{ ctx.min_amount }}
14
+ AND amount <= {{ ctx.max_amount }}
15
+
16
+ {%- endif -%}
17
+ {%- endmacro -%}
@@ -0,0 +1,26 @@
1
+ from squirrels import arguments as args
2
+ import polars as pl, pandas as pd
3
+
4
+
5
+ def main(sqrl: args.BuildModelArgs) -> pl.LazyFrame | pl.DataFrame | pd.DataFrame:
6
+ """
7
+ Create a build model by joining/processing sources or other build models to form a new
8
+ Python DataFrame (using polars LazyFrame, polars DataFrame, or pandas DataFrame).
9
+ """
10
+ # sqrl.ref() can be used on a sources, seeds, or other build models
11
+ expenses_df = sqrl.ref("src_transactions")
12
+ categories_df = sqrl.ref("seed_categories")
13
+ subcategories_df = sqrl.ref("seed_subcategories")
14
+
15
+ df = expenses_df \
16
+ .join(subcategories_df, on="subcategory_id", how="left") \
17
+ .join(categories_df, on="category_id", how="left")
18
+
19
+ df = df.with_columns(
20
+ pl.col("date").dt.strftime("%Y-%m").alias("month"),
21
+ pl.col("date").dt.strftime("%Y-%m-%d").alias("date"),
22
+ )
23
+
24
+ return df.select(
25
+ "id", "date", "month", "category_id", "category", "subcategory_id", "subcategory", "amount", "description"
26
+ )
@@ -0,0 +1,16 @@
1
+ {#- DuckDB dialect -#}
2
+
3
+ SELECT a.id,
4
+ STRFTIME(a.date, '%Y-%m-%d') AS date,
5
+ STRFTIME(a.date, '%Y-%m') AS month,
6
+ c.category_id,
7
+ c.category,
8
+ b.subcategory_id,
9
+ b.subcategory,
10
+ a.amount,
11
+ a.description
12
+
13
+ {# ref() can be used on a sources, seeds, or other build models -#}
14
+ FROM {{ ref("src_transactions") }} AS a
15
+ LEFT JOIN {{ ref("seed_subcategories") }} AS b ON a.subcategory_id = b.subcategory_id
16
+ LEFT JOIN {{ ref("seed_categories") }} AS c ON b.category_id = c.category_id
@@ -0,0 +1,57 @@
1
+ description: |
2
+ This is an example of a build model. It adds a new column called "month" to the source table "src_transactions".
3
+
4
+ materialization: TABLE # optional - defaults to "VIEW" for SQL models, ignored and always a "TABLE" for Python models
5
+
6
+ depends_on: # optional for SQL models - the "ref" macro also adds to this set
7
+ - src_transactions
8
+ - seed_categories
9
+ - seed_subcategories
10
+
11
+ columns:
12
+ - name: id
13
+ depends_on:
14
+ - src_transactions.id
15
+ pass_through: true
16
+
17
+ - name: date
18
+ type: string
19
+ description: The day of the transaction as a string in 'YYYY-MM-DD' format
20
+ depends_on:
21
+ - src_transactions.date
22
+
23
+ - name: month
24
+ type: string
25
+ description: The month of the transaction as a string in 'YYYY-MM' format
26
+ depends_on:
27
+ - src_transactions.date
28
+
29
+ - name: category_id
30
+ depends_on:
31
+ - seed_categories.category_id
32
+ pass_through: true
33
+
34
+ - name: category
35
+ depends_on:
36
+ - seed_categories.category
37
+ pass_through: true
38
+
39
+ - name: subcategory_id
40
+ depends_on:
41
+ - seed_subcategories.subcategory_id
42
+ pass_through: true
43
+
44
+ - name: subcategory
45
+ depends_on:
46
+ - seed_subcategories.subcategory
47
+ pass_through: true
48
+
49
+ - name: amount
50
+ depends_on:
51
+ - src_transactions.amount
52
+ pass_through: true
53
+
54
+ - name: description
55
+ depends_on:
56
+ - src_transactions.description
57
+ pass_through: true
@@ -0,0 +1,12 @@
1
+ {#- SQLite dialect (based on connection used) -#}
2
+
3
+ SELECT STRFTIME('%Y-%m', date) AS month
4
+ , printf('%.2f', SUM(amount)) as total_amount
5
+
6
+ FROM {{ source("src_transactions") }}
7
+
8
+ WHERE {{ date_and_amount_filters(use_from_range=false) }}
9
+
10
+ GROUP BY 1
11
+
12
+ ORDER BY 1 DESC
@@ -0,0 +1,26 @@
1
+ description: |
2
+ This is an example of a database view model. It finds the total amount spent by month.
3
+
4
+ Parameters are available to filter the date and amount of the transactions.
5
+
6
+ connection: default # optional - if not provided, will use default connection specified in the SQRL_CONNECTIONS__DEFAULT_NAME_USED setting
7
+
8
+ translate_to_duckdb: true # optional - default is false - if true, then the model will be translated to duckdb for supported dialects
9
+
10
+ depends_on: # optional - the "source" macro also adds to this set
11
+ - src_transactions
12
+
13
+ columns:
14
+ - name: month
15
+ type: string
16
+ description: The months for which the amount is aggregated by, in descending order
17
+ category: dimension
18
+ depends_on:
19
+ - src_transactions.date
20
+
21
+ - name: total_amount
22
+ type: float
23
+ description: The total amount spent by month
24
+ category: measure
25
+ depends_on:
26
+ - src_transactions.amount
@@ -0,0 +1,37 @@
1
+ from squirrels import arguments as args
2
+ import polars as pl, pandas as pd
3
+
4
+
5
+ def main(sqrl: args.ModelArgs) -> pl.LazyFrame | pl.DataFrame | pd.DataFrame:
6
+ """
7
+ Create federated models by joining/processing dependent models (sources, seeds, builds, dbviews, other federates, etc.) to
8
+ form a new Python DataFrame (using polars LazyFrame, polars DataFrame, or pandas DataFrame).
9
+ """
10
+ df = sqrl.ref("build_example")
11
+
12
+ df = df.filter(
13
+ (pl.col("date") >= sqrl.ctx["start_date_from_range"]) &
14
+ (pl.col("date") <= sqrl.ctx["end_date_from_range"]) &
15
+ (pl.col("amount") >= sqrl.ctx["min_amount_from_range"]) &
16
+ (pl.col("amount") <= sqrl.ctx["max_amount_from_range"])
17
+ )
18
+
19
+ if sqrl.ctx["has_categories"]:
20
+ categories: list[str] = sqrl.ctx["categories"]
21
+ df = df.filter(pl.col("category_id").is_in(categories))
22
+
23
+ if sqrl.ctx["has_subcategories"]:
24
+ subcategories: list[str] = sqrl.ctx["subcategories"]
25
+ df = df.filter(pl.col("subcategory_id").is_in(subcategories))
26
+
27
+ dimension_cols: list[str] = sqrl.ctx["group_by_cols"]
28
+ df = df.group_by(dimension_cols).agg(
29
+ pl.sum("amount").cast(pl.Decimal(precision=15, scale=2)).alias("total_amount")
30
+ )
31
+ df = df.rename(sqrl.ctx["column_to_alias_mapping"])
32
+
33
+ order_by_cols: list[str] = sqrl.ctx["order_by_cols"]
34
+ df = df.select(*order_by_cols, "total_amount") \
35
+ .sort(order_by_cols, descending=True)
36
+
37
+ return df
@@ -0,0 +1,19 @@
1
+ {#- DuckDB dialect -#}
2
+
3
+ SELECT {{ ctx.select_dim_cols | join }}
4
+ , CAST(SUM(amount) AS DECIMAL(15, 2)) as total_amount
5
+
6
+ {# ref() can be used on a sources, seeds, builds, dbviews, or other federate models -#}
7
+ FROM {{ ref("build_example") }} AS a
8
+
9
+ WHERE {{ date_and_amount_filters(use_from_range=true) }}
10
+ {%- if ctx.has_categories %}
11
+ AND category_id IN ({{ ctx.categories | quote_and_join }})
12
+ {%- endif %}
13
+ {%- if ctx.has_subcategories %}
14
+ AND subcategory_id IN ({{ ctx.subcategories | quote_and_join }})
15
+ {%- endif %}
16
+
17
+ GROUP BY {{ ctx.group_by_cols | join }}
18
+
19
+ ORDER BY {{ ctx.order_by_cols_desc | join }}
@@ -0,0 +1,65 @@
1
+ description: |
2
+ This is an example of a federate view model. It takes the build example model and groups or filters the results based on the parameter selections provided.
3
+
4
+ Parameters are available to specify the group by dimension and filter by date, amount of the transaction, category, and subcategory.
5
+
6
+ depends_on: # optional for SQL models - the "ref" macro also adds to this set
7
+ - build_example
8
+
9
+ eager: false # optional - defaults to false. Only applies to SQL models.
10
+
11
+ columns:
12
+ - name: date
13
+ type: string
14
+ condition: parameter 'group_by' (Group By) is 'trans' (Transaction)
15
+ description: The date of the transaction in 'YYYY-MM-DD' format, in descending order
16
+ category: dimension
17
+ depends_on:
18
+ - build_example.date
19
+
20
+ - name: description
21
+ type: string
22
+ condition: parameter 'group_by' (Group By) is 'trans' (Transaction)
23
+ description: The description of the transaction
24
+ category: dimension
25
+ depends_on:
26
+ - build_example.description
27
+
28
+ - name: day
29
+ type: string
30
+ condition: parameter 'group_by' (Group By) is 'day' (Day)
31
+ description: The day for which the amount is aggregated by, in descending order
32
+ category: dimension
33
+ depends_on:
34
+ - build_example.date
35
+
36
+ - name: month
37
+ type: string
38
+ condition: parameter 'group_by' (Group By) is 'month' (Month)
39
+ description: The month for which the amount is aggregated by, in descending order
40
+ category: dimension
41
+ depends_on:
42
+ - build_example.month
43
+
44
+ - name: category
45
+ type: string
46
+ condition: parameter `group_by` (Group By) is `trans` (Transaction), `cat` (Category), or `subcat` (Subcategory)
47
+ description: The category for which the amount is aggregated by
48
+ category: dimension
49
+ depends_on:
50
+ - build_example.category
51
+
52
+ - name: subcategory
53
+ type: string
54
+ condition: parameter `group_by` (Group By) is `trans` (Transaction) or `subcat` (Subcategory)
55
+ description: The subcategory for which the amount is aggregated by
56
+ category: dimension
57
+ depends_on:
58
+ - build_example.subcategory
59
+
60
+ - name: total_amount
61
+ type: float
62
+ description: The total amount spent by the group by dimension
63
+ category: measure
64
+ depends_on:
65
+ - build_example.total_amount
@@ -0,0 +1,38 @@
1
+ sources:
2
+ - name: src_transactions
3
+ description: "The source table for transactions" # optional
4
+ connection: default # optional - if not provided, will use the connection named "default" or the default connection specified in settings
5
+ table: expenses # optional - if not provided, will use the "name" field of the source
6
+ load_to_vdl: true # optional - default is false - other than dbview models (with translate_to_duckdb set to false), other models can only reference this source if load_to_vdl is true or connection type is duckdb
7
+
8
+ update_hints:
9
+ increasing_column: date # optional - if not provided, will always do full refresh, otherwise uses this column for incremental loads
10
+ strictly_increasing: false # optional - default is true - if false, then maximum value of column is removed before incremental load is performed
11
+
12
+ primary_key: [id] # optional - if not provided, then this is an insert-only table for incremental loads
13
+
14
+ columns: # optional - if load_to_vdl is true, then only the columns listed here are loaded to the Virtual Data Lake (VDL)
15
+ - name: id
16
+ type: string
17
+ description: The unique identifier for the transaction
18
+ category: dimension
19
+
20
+ - name: date
21
+ type: date
22
+ description: The date of the transaction
23
+ category: dimension
24
+
25
+ - name: subcategory_id
26
+ type: string
27
+ description: The ID of the subcategory of the transaction
28
+ category: dimension
29
+
30
+ - name: amount
31
+ type: float
32
+ description: The amount of the transaction
33
+ category: measure
34
+
35
+ - name: description
36
+ type: string
37
+ description: The description of the transaction
38
+ category: dimension