Skip to content

Conversation

@nikhil-zlai
Copy link
Contributor

@nikhil-zlai nikhil-zlai commented Jan 21, 2025

Summary

accept 1h, 30d etc as valid entries to the Windows arg of Aggregation.

Checklist

  • Added Unit Tests
  • Covered by existing CI
  • Integration tested
  • Documentation update

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced window specification in GroupBy functionality, now supporting string-based time window definitions (e.g., "7d", "1h").
  • Improvements

    • Simplified window configuration syntax across multiple files.
    • Removed deprecated Window and TimeUnit class imports.
    • Improved code readability in various sample and test files.
  • Tests

    • Added new test case to validate string-based window specifications.
  • Documentation

    • Updated documentation examples to reflect new window specification method.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2025

Walkthrough

The pull request introduces a significant enhancement to the Chronon library's window specification mechanism. The core change allows developers to specify time windows using simple string representations (like "7d" or "1h") instead of constructing Window and TimeUnit objects. This modification simplifies the API, reduces boilerplate code, and provides a more intuitive way to define aggregation windows across multiple files and test cases.

Changes

File Change Summary
api/py/ai/chronon/group_by.py Added string window support in Aggregation function with normalize method
api/py/test/sample/group_bys/* Replaced Window(length, timeUnit) with string window representations
docs/examples/main.py Updated window specifications to use string format
docs/source/authoring_features/GroupBy.md Simplified window size examples
api/py/test/test_group_by.py Added test for string window handling
api/py/test/test_run.py Removed argparse import

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant GroupBy as GroupBy Function
    participant Aggregation as Aggregation Function
    participant Window as Window Converter

    Dev->>GroupBy: Specify windows=["7d"]
    GroupBy->>Aggregation: Pass string windows
    Aggregation->>Window: Normalize windows
    Window-->>Aggregation: Return Window objects
    Aggregation->>GroupBy: Create aggregation
Loading

Poem

🕰️ Windows of time, once complex and tight,
Now dance as strings, pure and light!
From Window(7, Days) to simply "7d"
Code flows smoother, developers' glee!
Chronon evolves, simplicity reigns bright 🌟

Warning

Review ran into problems

🔥 Problems

GitHub Actions: Resource not accessible by integration - https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-repository.

Please grant the required permissions to the CodeRabbit GitHub App under the organization or repository settings.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between f8f0ec6 and 323a0af.

📒 Files selected for processing (1)
  • api/py/ai/chronon/windows.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
api/py/ai/chronon/windows.py

49-49: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: no_spark_scala_tests
🔇 Additional comments (4)
api/py/ai/chronon/windows.py (4)

4-5: LGTM! Clean and focused implementation.


8-9: LGTM! Clean and focused implementation.


12-46: LGTM! Clean parsing with proper validation.


47-50: Chain exceptions for better debugging.

Use raise ... from e to preserve the exception chain.

-        if "invalid literal for int()" in str(e):
-            raise ValueError(f"Invalid numeric value in duration: {value}")
-        raise e from None
+        if "invalid literal for int()" in str(e):
+            raise ValueError(f"Invalid numeric value in duration: {value}") from e
+        raise e from None
🧰 Tools
🪛 Ruff (0.8.2)

49-49: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
api/py/test/sample/group_bys/quickstart/returns.py (1)

38-38: LGTM! Clean implementation with good documentation.

Consider adding a comment explaining the choice of these specific window sizes (3d, 14d, 30d).

Also applies to: 46-50

api/py/test/test_group_by.py (1)

257-273: Consider adding edge case tests.

While the test covers basic functionality, consider adding tests for:

  • Invalid string formats
  • Zero or negative durations
  • Mixed case units (e.g., "1H", "1D")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 8e13f55 and d3d65a4.

📒 Files selected for processing (17)
  • api/py/ai/chronon/group_by.py (5 hunks)
  • api/py/test/sample/group_bys/kaggle/clicks.py (2 hunks)
  • api/py/test/sample/group_bys/kaggle/outbrain.py (3 hunks)
  • api/py/test/sample/group_bys/quickstart/purchases.py (2 hunks)
  • api/py/test/sample/group_bys/quickstart/returns.py (1 hunks)
  • api/py/test/sample/group_bys/risk/transaction_events.py (2 hunks)
  • api/py/test/sample/group_bys/sample_team/entity_sample_group_by_from_module.py (1 hunks)
  • api/py/test/sample/group_bys/sample_team/event_sample_group_by.py (2 hunks)
  • api/py/test/sample/group_bys/sample_team/group_by_with_kwargs.py (1 hunks)
  • api/py/test/sample/group_bys/sample_team/sample_group_by_from_module.py (1 hunks)
  • api/py/test/sample/group_bys/sample_team/sample_non_prod_group_by.py (1 hunks)
  • api/py/test/sample/joins/sample_team/sample_label_join_with_agg.py (1 hunks)
  • api/py/test/test_group_by.py (1 hunks)
  • api/py/test/test_run.py (0 hunks)
  • docs/examples/main.py (1 hunks)
  • docs/source/authoring_features/GroupBy.md (3 hunks)
  • docs/source/index.rst (1 hunks)
💤 Files with no reviewable changes (1)
  • api/py/test/test_run.py
✅ Files skipped from review due to trivial changes (2)
  • docs/source/authoring_features/GroupBy.md
  • docs/examples/main.py
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: no_spark_scala_tests
🔇 Additional comments (17)
api/py/test/sample/group_bys/sample_team/entity_sample_group_by_from_module.py (1)

20-20: LGTM! String-based window specification is cleaner.

Also applies to: 28-28

api/py/test/sample/group_bys/sample_team/sample_non_prod_group_by.py (1)

27-27: LGTM! Clean changes with good style.

Also applies to: 32-32

api/py/test/sample/group_bys/sample_team/sample_group_by_from_module.py (1)

35-35: LGTM! Consistent with other changes.

api/py/test/sample/group_bys/sample_team/group_by_with_kwargs.py (1)

36-36: LGTM! Verify string format parsing.

String format looks good, but let's verify the parsing of time units.

✅ Verification successful

Window format "7d" is valid and properly handled

Found validation logic in ai/chronon/group_by.py that confirms the format is correct and enforced.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for window string format validation
rg -l 'def (parse|validate|normalize).*window' api/py/

Length of output: 56


Script:

#!/bin/bash
# Find window-related code
rg -l "window" api/py/

# Find time duration patterns
rg -l "[0-9]+[dhms]" api/py/

# Find test cases with window strings
rg -A 3 "window.*['\"][0-9]+[dhms]['\"]" api/py/

Length of output: 11291

api/py/test/sample/group_bys/sample_team/event_sample_group_by.py (1)

16-16: LGTM! Clean transition to string windows.

Also applies to: 26-26

api/py/test/sample/group_bys/risk/transaction_events.py (1)

3-3: LGTM! Well-structured window definitions.

Good use of a reusable window_sizes variable.

Also applies to: 23-23, 35-35, 40-40

api/py/test/sample/joins/sample_team/sample_label_join_with_agg.py (1)

40-40: LGTM! Clean window string format.

api/py/test/sample/group_bys/quickstart/purchases.py (2)

37-37: LGTM! Clean string-based window definitions.

The new string format ("3d", "14d", "30d") is more concise and readable than the previous Window objects.


44-56: LGTM! Aggregations correctly use string windows.

The aggregations properly implement the new string-based window format while maintaining the same functionality.

api/py/test/sample/group_bys/kaggle/clicks.py (1)

57-61: LGTM! Consistent use of string windows.

All aggregations correctly use the "3d" string format.

api/py/test/sample/group_bys/kaggle/outbrain.py (1)

44-52: LGTM! Template function correctly implements string windows.

The ctr_group_by template function properly uses "3d" string format across all aggregations.

api/py/test/test_group_by.py (1)

275-281: LGTM! Thorough verification of window conversion.

The assertions properly verify both the conversion to Window objects and metadata preservation.

api/py/ai/chronon/group_by.py (4)

18-18: LGTM!

Import required for string window parsing.


138-138: LGTM!

Type hint and docstring accurately reflect string window support.

Also applies to: 153-153


428-428: LGTM!

Example accurately demonstrates string window usage.


168-177: Verify string window format validation.

Ensure that window_utils._from_str validates the string format and raises clear exceptions for invalid formats like "7x" or "-1d".

✅ Verification successful

String window format validation is properly handled.

The normalize() function already provides a clear error message specifying the expected format ('7d', '24h'). The extensive usage across test files and examples demonstrates consistent validation of this format.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for window string validation logic
ast-grep --pattern 'def _from_str($param) {
  $$$
}'

Length of output: 54


Script:

#!/bin/bash
# Try both ast-grep and ripgrep to find _from_str
ast-grep --pattern 'def _from_str($_):
    $$$'

# Backup search with ripgrep
rg "_from_str" -A 10

Length of output: 812


Script:

#!/bin/bash
# Find window_utils module
fd window_utils

# Search for window_utils definition
rg "class window_utils|window_utils =" -A 10

Length of output: 64


Script:

#!/bin/bash
# Find Window-related imports and string parsing
rg "from.*Window|import.*Window" -A 2
rg "['\"]\d+[dhm]['\"]" -A 5 -B 5

Length of output: 53435

docs/source/index.rst (1)

114-114: LGTM!

Documentation example updated to reflect new string window syntax, improving readability.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
api/py/ai/chronon/windows.py (1)

26-27: Add more input validations.

Consider:

  1. Strip whitespace from input
  2. Add upper limit for length
  3. Handle scientific notation
-    if not s or len(s) < 2:
+    if not s or len(s.strip()) < 2:
         raise ValueError(f"Invalid duration format: {s}")

     try:
         length = int(value)
-        if length <= 0:
+        if length <= 0 or length > 365:  # Example max limit
             raise ValueError(f"Duration must be positive: {s}")

Also applies to: 33-37

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between d3d65a4 and f8f0ec6.

📒 Files selected for processing (1)
  • api/py/ai/chronon/windows.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
api/py/ai/chronon/windows.py

49-49: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: no_spark_scala_tests
🔇 Additional comments (2)
api/py/ai/chronon/windows.py (2)

4-5: LGTM! Clean helper function.


8-9: LGTM! Clean helper function.

Comment on lines 47 to 50
except ValueError as e:
if "invalid literal for int()" in str(e):
raise ValueError(f"Invalid numeric value in duration: {value}")
raise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Chain exceptions for better debugging.

Use raise ... from e to preserve the exception chain.

-        if "invalid literal for int()" in str(e):
-            raise ValueError(f"Invalid numeric value in duration: {value}")
-        raise
+        if "invalid literal for int()" in str(e):
+            raise ValueError(f"Invalid numeric value in duration: {value}") from e
+        raise e from None
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
except ValueError as e:
if "invalid literal for int()" in str(e):
raise ValueError(f"Invalid numeric value in duration: {value}")
raise
except ValueError as e:
if "invalid literal for int()" in str(e):
raise ValueError(f"Invalid numeric value in duration: {value}") from e
raise e from None
🧰 Tools
🪛 Ruff (0.8.2)

49-49: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

Copy link
Contributor

@piyush-zlai piyush-zlai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes itself are great for dev ergonomics, thanks for putting this up.
Might be worth OSSing this one as it will be part of the tax folks have to pay when migrating from our fork to vanilla OSS if they have to..

@nikhil-zlai nikhil-zlai merged commit b27d34e into main Jan 21, 2025
5 checks passed
@nikhil-zlai nikhil-zlai deleted the py_api_windows branch January 21, 2025 17:48
@nikhil-zlai
Copy link
Contributor Author

Changes itself are great for dev ergonomics, thanks for putting this up. Might be worth OSSing this one as it will be part of the tax folks have to pay when migrating from our fork to vanilla OSS if they have to..

Agree - this is very oss-able.

@@ -0,0 +1,50 @@
import ai.chronon.api.common.ttypes as common


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know u already merged this but was wondering if it would make sense to use a lib for this? Ex:

from datetime import datetime
import pandas as pd

def parse_timedelta_with_pandas(delta_str: str, base_time: datetime = None) -> datetime:
    if base_time is None:
        base_time = datetime.now()

    # Convert delta string to pandas Timedelta and add to the base time
    timedelta = pd.Timedelta(delta_str)
    return base_time + timedelta.to_pytimedelta()

# Example Usage
print(parse_timedelta_with_pandas("1h"))  # Adds 1 hour
print(parse_timedelta_with_pandas("30d"))  # Adds 30 days
print(parse_timedelta_with_pandas("2w"))  # Adds 2 weeks

kumar-zlai pushed a commit that referenced this pull request Apr 25, 2025
## Summary

accept `1h`, `30d` etc as valid entries to the Windows arg of
Aggregation.


## Checklist
- [x] Added Unit Tests
- [x] Covered by existing CI
- [x] Integration tested
- [x] Documentation update



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced window specification in GroupBy functionality, now supporting
string-based time window definitions (e.g., "7d", "1h").

- **Improvements**
	- Simplified window configuration syntax across multiple files.
	- Removed deprecated `Window` and `TimeUnit` class imports.
	- Improved code readability in various sample and test files.

- **Tests**
	- Added new test case to validate string-based window specifications.

- **Documentation**
- Updated documentation examples to reflect new window specification
method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
kumar-zlai pushed a commit that referenced this pull request Apr 29, 2025
## Summary

accept `1h`, `30d` etc as valid entries to the Windows arg of
Aggregation.


## Checklist
- [x] Added Unit Tests
- [x] Covered by existing CI
- [x] Integration tested
- [x] Documentation update



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced window specification in GroupBy functionality, now supporting
string-based time window definitions (e.g., "7d", "1h").

- **Improvements**
	- Simplified window configuration syntax across multiple files.
	- Removed deprecated `Window` and `TimeUnit` class imports.
	- Improved code readability in various sample and test files.

- **Tests**
	- Added new test case to validate string-based window specifications.

- **Documentation**
- Updated documentation examples to reflect new window specification
method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
chewy-zlai pushed a commit that referenced this pull request May 15, 2025
## Summary

accept `1h`, `30d` etc as valid entries to the Windows arg of
Aggregation.


## Checklist
- [x] Added Unit Tests
- [x] Covered by existing CI
- [x] Integration tested
- [x] Documentation update



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced window specification in GroupBy functionality, now supporting
string-based time window definitions (e.g., "7d", "1h").

- **Improvements**
	- Simplified window configuration syntax across multiple files.
	- Removed deprecated `Window` and `TimeUnit` class imports.
	- Improved code readability in various sample and test files.

- **Tests**
	- Added new test case to validate string-based window specifications.

- **Documentation**
- Updated documentation examples to reflect new window specification
method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
chewy-zlai pushed a commit that referenced this pull request May 15, 2025
## Summary

accept `1h`, `30d` etc as valid entries to the Windows arg of
Aggregation.


## Checklist
- [x] Added Unit Tests
- [x] Covered by existing CI
- [x] Integration tested
- [x] Documentation update



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced window specification in GroupBy functionality, now supporting
string-based time window definitions (e.g., "7d", "1h").

- **Improvements**
	- Simplified window configuration syntax across multiple files.
	- Removed deprecated `Window` and `TimeUnit` class imports.
	- Improved code readability in various sample and test files.

- **Tests**
	- Added new test case to validate string-based window specifications.

- **Documentation**
- Updated documentation examples to reflect new window specification
method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
chewy-zlai pushed a commit that referenced this pull request May 16, 2025
## Summary

accept `1h`, `30d` etc as valid entries to the Windows arg of
Aggregation.


## Cheour clientslist
- [x] Added Unit Tests
- [x] Covered by existing CI
- [x] Integration tested
- [x] Documentation update



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
- Enhanced window specification in GroupBy functionality, now supporting
string-based time window definitions (e.g., "7d", "1h").

- **Improvements**
	- Simplified window configuration syntax across multiple files.
	- Removed deprecated `Window` and `TimeUnit` class imports.
	- Improved code readability in various sample and test files.

- **Tests**
	- Added new test case to validate string-based window specifications.

- **Documentation**
- Updated documentation examples to reflect new window specification
method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@coderabbitai coderabbitai bot mentioned this pull request Jul 28, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants