Skip to content

new: add get_security_dividend_details() for announced dividend dates#66

Merged
gboudreau merged 1 commit into
gboudreau:mainfrom
edanvoye:feat/security-dividend-details
Jun 1, 2026
Merged

new: add get_security_dividend_details() for announced dividend dates#66
gboudreau merged 1 commit into
gboudreau:mainfrom
edanvoye:feat/security-dividend-details

Conversation

@edanvoye
Copy link
Copy Markdown
Contributor

@edanvoye edanvoye commented Jun 1, 2026

Wealthsimple's web app fetches a security's declared dividend schedule via the FetchSecurityDividendDetails query, exposing Security.events with exDividendDate / payableDate / recordDate (plus yield and dividendFrequency). None of the existing queries surface these dates, so consumers had to estimate payment dates from ex-dividend cadences.

  • Add the FetchSecurityDividendDetails query to GRAPHQL_QUERIES (the web app's own query, verbatim).
  • Add WealthsimpleAPI.get_security_dividend_details(security_id, currency=None), mirroring get_security_market_data / get_security_historical_quotes.

Note: events is an empty list until the issuer announces the next dividend.

Summary by CodeRabbit

  • New Features
    • Added new API method to fetch comprehensive security dividend details, including dividend yield, dividend events (ex-dividend, payable, and record dates), and dividend payment frequency. The method supports optional currency-based filtering, enabling flexible queries across different international markets for enhanced dividend data retrieval and analysis.

Wealthsimple's web app fetches a security's declared dividend schedule via
the FetchSecurityDividendDetails query, exposing Security.events with
exDividendDate / payableDate / recordDate (plus yield and dividendFrequency).
None of the existing queries surface these dates, so consumers had to estimate
payment dates from ex-dividend cadences.

- Add the FetchSecurityDividendDetails query to GRAPHQL_QUERIES (the web app's
  own query, verbatim).
- Add WealthsimpleAPI.get_security_dividend_details(security_id, currency=None),
  mirroring get_security_market_data / get_security_historical_quotes.

Note: `events` is an empty list until the issuer announces the next dividend.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds support for fetching dividend-related security details. A new GraphQL query definition retrieves security data including optional currency-scoped yield fundamentals, dividend-related event dates, and stock dividend frequency. A corresponding public API method constructs GraphQL variables from a security ID and optional currency parameter, executes the query, and returns the security object.

Changes

Security Dividend Details

Layer / File(s) Summary
GraphQL query definition and API method
ws_api/graphql_queries.py, ws_api/wealthsimple_api.py
GraphQL query FetchSecurityDividendDetails fetches security with optional currency-scoped yield, dividend events (ex-dividend, payable, record dates), and stock dividend frequency. Public method get_security_dividend_details(security_id, currency=None) executes the query and returns the security object.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • gboudreau/ws-api-python#60: Both PRs extend GraphQL-wrapper methods on the API using the same do_graphql_query + variables pattern to add dividend-related endpoints.

Poem

🐰 A query for dividends, oh so divine,
Yields and events in one fine design,
From GraphQL fields to API clean,
Wealth details now fully seen! 💰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a new method get_security_dividend_details() for retrieving announced dividend dates, which matches the primary objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ws_api/wealthsimple_api.py`:
- Line 693: The function signature for get_security_dividend_details currently
uses an implicit Optional by declaring currency: str = None; update the
signature to use an explicit Optional type (e.g., currency: str | None = None)
so it satisfies Ruff RUF013; locate the get_security_dividend_details definition
and replace the parameter annotation accordingly (or alternatively import and
use typing.Optional if you prefer) and run linters to confirm the RUF013 warning
is resolved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ab9ce190-7b77-470b-9cda-7747d0d87d88

📥 Commits

Reviewing files that changed from the base of the PR and between 40dcdee and 403d563.

📒 Files selected for processing (2)
  • ws_api/graphql_queries.py
  • ws_api/wealthsimple_api.py


return value

def get_security_dividend_details(self, security_id: str, currency: str = None):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify implicit-Optional patterns in Python signatures (read-only).
rg -nP --type=py '\bdef\s+\w+\(.*:\s*[^=,\n]+\s*=\s*None'

Repository: gboudreau/ws-api-python

Length of output: 462


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show surrounding code for the flagged method
echo "=== ws_api/wealthsimple_api.py: lines 670-730 ==="
nl -ba ws_api/wealthsimple_api.py | sed -n '670,730p'

# Find Ruff config and whether RUF013 is referenced/enabled
echo
echo "=== Ruff config files ==="
ls -1 pyproject.toml ruff.toml setup.cfg .ruff.toml 2>/dev/null || true

echo
echo "=== Search for RUF013 in repo ==="
rg -n "RUF013" -S .

Repository: gboudreau/ws-api-python

Length of output: 178


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== ws_api/wealthsimple_api.py: lines 680-710 (context) ==="
# Use sed (nl isn't available)
sed -n '680,710p' ws_api/wealthsimple_api.py

echo
echo "=== ws_api/wealthsimple_api.py: lines 688-700 (tight) ==="
sed -n '688,700p' ws_api/wealthsimple_api.py

echo
echo "=== Ruff config files (common locations) ==="
ls -1 pyproject.toml ruff.toml setup.cfg .ruff.toml .config/ruff.toml 2>/dev/null || true

echo
echo "=== Search for RUF013 in repo ==="
rg -n "RUF013" -S . || true

echo
echo "=== Search for Ruff 'select'/'ignore' mentioning Optional/implicit ==="
rg -n "ruff|select|ignore|RUF0|implicit|Optional|PEP 484" -S pyproject.toml ruff.toml setup.cfg .ruff.toml 2>/dev/null || true

Repository: gboudreau/ws-api-python

Length of output: 2364


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== ruff.toml (top 120 lines) ==="
sed -n '1,120p' ruff.toml

echo
echo "=== ruff.toml (rest, if any) ==="
sed -n '121,220p' ruff.toml 2>/dev/null || true

echo
echo "=== ruff.toml: look for RUF / implicit / Optional in config ==="
rg -n "select|ignore|RUF|implicit|Optional" ruff.toml

echo
echo "=== ws_api/wealthsimple_api.py: examples of existing '| None' signatures ==="
sed -n '1,80p' ws_api/wealthsimple_api.py
echo
sed -n '430,490p' ws_api/wealthsimple_api.py

Repository: gboudreau/ws-api-python

Length of output: 6136


🏁 Script executed:

#!/bin/bash
# Verify implicit-Optional patterns in Python signatures (read-only).
rg -nP --type=py '\bdef\s+\w+\(.*:\s*[^=,\n]+\s*=\s*None'

Repository: gboudreau/ws-api-python

Length of output: 462


🌐 Web query:

Ruff RUF013 implicit Optional str = None

💡 Result:

RUF013 is a lint rule in the Ruff Python linter that detects and flags "implicit Optional" type annotations [1]. What it does: The rule checks for function parameters where the type annotation is specified (e.g., str) but the default value is None, without explicitly marking the type as Optional [1]. PEP 484 prohibits this practice because it is considered ambiguous and inconsistent with the broader type system [1]. Example: Instead of the implicit pattern: def foo(arg: str = None): pass Ruff recommends: from typing import Optional def foo(arg: Optional[str] = None): pass Or, for Python 3.10 and later: def foo(arg: str | None = None): pass Key Details: - Autofix: Ruff provides an automatic fix for this issue [1][2]. If the lint.future-annotations setting is enabled, Ruff may also automatically add from future import annotations to the file, which allows the use of the | operator on Python versions earlier than 3.10 [1][3][4]. - Safety: The autofix is marked as "unsafe" by Ruff because it changes type hints and assumes the provided default value is appropriate, which might not always be the case [1]. - Limitations: The rule does not support type aliases, which may lead to false negatives [1][2]. Additionally, it treats some custom types as Any (which implicitly includes None), meaning those cases may not be flagged [5].

Citations:


🏁 Script executed:

#!/bin/bash
# Verify implicit-Optional patterns in Python signatures (read-only).
rg -nP --type=py '\bdef\s+\w+\(.*:\s*[^=,\n]+\s*=\s*None'

Repository: gboudreau/ws-api-python

Length of output: 462


🏁 Script executed:

#!/bin/bash
# Verify implicit-Optional patterns in Python signatures (read-only).
rg -nP --type=py '\bdef\s+\w+\(.*:\s*[^=,\n]+\s*=\s*None'

Repository: gboudreau/ws-api-python

Length of output: 462


🏁 Script executed:

#!/bin/bash
# Find function parameters defaulting to None where the type is NOT explicitly Optional (`| None` / `Optional[...]`)
rg -nP --type=py '\bdef\s+\w+\([^)]*\b\w+\s*:\s*(?![^=,\n]*\|\s*None)(?![^=,\n]*\bOptional\[)[^=,\n]+\s*=\s*None'

Repository: gboudreau/ws-api-python

Length of output: 183


Use explicit Optional typing for currency (RUF013)

get_security_dividend_details uses currency: str = None, which triggers Ruff’s RUF013 implicit-Optional lint. Change it to currency: str | None = None.

✅ Proposed fix
-    def get_security_dividend_details(self, security_id: str, currency: str = None):
+    def get_security_dividend_details(
+        self, security_id: str, currency: str | None = 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
def get_security_dividend_details(self, security_id: str, currency: str = None):
def get_security_dividend_details(
self, security_id: str, currency: str | None = None
):
🧰 Tools
🪛 Ruff (0.15.14)

[warning] 693-693: PEP 484 prohibits implicit Optional

Convert to T | None

(RUF013)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ws_api/wealthsimple_api.py` at line 693, The function signature for
get_security_dividend_details currently uses an implicit Optional by declaring
currency: str = None; update the signature to use an explicit Optional type
(e.g., currency: str | None = None) so it satisfies Ruff RUF013; locate the
get_security_dividend_details definition and replace the parameter annotation
accordingly (or alternatively import and use typing.Optional if you prefer) and
run linters to confirm the RUF013 warning is resolved.

@gboudreau
Copy link
Copy Markdown
Owner

Salut Étienne ! :)

@gboudreau gboudreau merged commit 52d0660 into gboudreau:main Jun 1, 2026
1 check passed
gboudreau added a commit to gboudreau/ws-api-php that referenced this pull request Jun 1, 2026
Wealthsimple's web app fetches a security's declared dividend schedule via
the FetchSecurityDividendDetails query, exposing Security.events with
exDividendDate / payableDate / recordDate (plus yield and dividendFrequency).
None of the existing queries surface these dates, so consumers had to estimate
payment dates from ex-dividend cadences.

- Add the FetchSecurityDividendDetails query to getGraphQLQuery() (the web app's
  own query, verbatim).
- Add WealthsimpleAPI.getSecurityDividendDetails($security_id, $currency).

Note: `events` is an empty list until the issuer announces the next dividend.

Source: gboudreau/ws-api-python#66
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.

2 participants