Skip to content

Conversation

@nikochiko
Copy link
Member

Q/A checklist

  • I have tested my UI changes on mobile and they look acceptable
  • I have tested changes to the workflows in both the API and the UI
  • I have done a code review of my changes and looked at each line of the diff + the references of each function I have changed
  • My changes have not increased the import time of the server
How to check import time?

time python -c 'import server'

You can visualize this using tuna:

python3 -X importtime -c 'import server' 2> out.log && tuna out.log

To measure import time for a specific library:

$ time python -c 'import pandas'

________________________________________________________
Executed in    1.15 secs    fish           external
   usr time    2.22 secs   86.00 micros    2.22 secs
   sys time    0.72 secs  613.00 micros    0.72 secs

To reduce import times, import libraries that take a long time inside the functions that use them instead of at the top of the file:

def my_function():
    import pandas as pd
    ...

Legal Boilerplate

Look, I get it. The entity doing business as “Gooey.AI” and/or “Dara.network” was incorporated in the State of Delaware in 2020 as Dara Network Inc. and is gonna need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Dara Network Inc can use, modify, copy, and redistribute my contributions, under its choice of terms.

@coderabbitai
Copy link

coderabbitai bot commented Nov 14, 2025

📝 Walkthrough

Walkthrough

Adds a new exported icon constant keys in daras_ai_v2/icons.py. Introduces get_toolkit_name_by_slug(toolkit_slug: str) -> str in functions/composio_tools.py. Extends FunctionScopes: format_label gains an optional current_user parameter and two classmethods from_user_id and get_user_id_prefix_for_workspace. Updates render_inputs in functions/recipe_functions.py to pass current_user for certain tool scopes. Adds typed functions in functions/views.py to fetch and render integration authorizations and a new manage_integration_authorizations UI flow. Updates account UI to show "Keys & Authorizations" and call the new management UI. Minor UI rendering changes (gui.write → gui.caption) and removal of .semobold CSS class.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • functions/views.py — new HTTP fetching, filtering, preloading logic and UI rendering (highest attention).
  • FunctionScopes — label logic changes, new parsing classmethods, and signature update; verify edge cases and formatting.
  • Integration between recipe_functions.py, views.py, and routers/account.py — ensure correct propagation of current_user and safe forward references.
  • New helper get_toolkit_name_by_slug — confirm behavior when slug not found.
  • UI tweaks (gui.caption vs gui.write) and removal of .semobold — quick visual/regression check.

Suggested reviewers

  • devxpy

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The description matches the required template structure exactly, including the Q/A checklist, import time guidance, and legal boilerplate, but all checklist items remain unchecked indicating the review was not completed. Complete the Q/A checklist by checking off items as applicable, or provide explanations for any items that cannot be verified before merging.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a view for composio keys and integration authorizations, which matches the primary objective of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch composio-keys

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 848fdee and f8ea849.

📒 Files selected for processing (4)
  • daras_ai_v2/manage_api_keys_widget.py (1 hunks)
  • functions/views.py (1 hunks)
  • managed_secrets/widgets.py (1 hunks)
  • static/css/app.css (0 hunks)
💤 Files with no reviewable changes (1)
  • static/css/app.css
🧰 Additional context used
🧬 Code graph analysis (1)
functions/views.py (5)
functions/composio_tools.py (1)
  • get_toolkit_name_by_slug (270-275)
functions/models.py (5)
  • FunctionScopes (40-214)
  • ScopeParts (25-31)
  • get_user_id_for_scope (181-214)
  • from_user_id (160-174)
  • format_label (86-157)
app_users/models.py (1)
  • AppUser (90-262)
bots/models/published_run.py (1)
  • PublishedRun (118-346)
workspaces/models.py (2)
  • Workspace (105-454)
  • html_icon (409-416)
🪛 Ruff (0.14.5)
functions/views.py

20-20: Probable use of requests call without timeout

(S113)


90-94: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


98-99: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


107-107: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


110-110: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (2)
managed_secrets/widgets.py (1)

16-19: Switch to gui.caption improves consistency for intro text

Using gui.caption for the explanatory paragraph matches how captions are used elsewhere in this module and keeps the semantics (single string argument) intact. No issues spotted.

daras_ai_v2/manage_api_keys_widget.py (1)

15-26: Header block rendered via gui.caption is consistent and correct

The change to gui.caption for the API keys intro paragraph keeps behavior the same while matching the caption-based pattern used in related views. The f-string and interpolation remain unchanged and correct.


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

@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 (2)
functions/views.py (1)

79-91: Consider parenthesizing and expressions for clarity.

The chained and/or expressions could benefit from explicit parentheses to make operator precedence clear.

Apply this diff to improve readability:

                 published_run = (
-                    published_run_id
-                    and PublishedRun.objects.filter(
+                    (published_run_id
+                    and PublishedRun.objects.filter(
                         published_run_id=published_run_id
-                    ).first()
+                    ).first())
                     or None
                 )
                 app_user_id = scope_parts.get(ScopeParts.member)
                 app_user = (
-                    app_user_id
-                    and AppUser.objects.filter(id=app_user_id).first()
+                    (app_user_id
+                    and AppUser.objects.filter(id=app_user_id).first())
                     or None
                 )
functions/models.py (1)

159-174: Add explicit strict=True to zip() for safety.

The zip() call should specify strict=True to catch any unexpected mismatches between scope part keys and values.

Apply this diff:

         scope_values = {
             ScopeParts(part): value
-            for part, value in zip(user_id_scope_parts, parts[1::2])
+            for part, value in zip(user_id_scope_parts, parts[1::2], strict=True)
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a264fe5 and 958a61c.

📒 Files selected for processing (6)
  • daras_ai_v2/icons.py (1 hunks)
  • functions/composio_tools.py (1 hunks)
  • functions/models.py (2 hunks)
  • functions/recipe_functions.py (1 hunks)
  • functions/views.py (1 hunks)
  • routers/account.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
functions/models.py (2)
app_users/models.py (2)
  • AppUser (90-262)
  • full_name (161-177)
workspaces/models.py (2)
  • html_icon (409-416)
  • Workspace (105-454)
functions/views.py (4)
functions/composio_tools.py (1)
  • get_toolkit_name_by_slug (270-275)
functions/models.py (5)
  • FunctionScopes (40-214)
  • ScopeParts (25-31)
  • get_user_id_for_scope (181-214)
  • from_user_id (160-174)
  • format_label (86-157)
app_users/models.py (1)
  • AppUser (90-262)
bots/models/published_run.py (1)
  • PublishedRun (118-346)
routers/account.py (2)
functions/views.py (1)
  • manage_integration_authorizations (54-114)
routers/root.py (1)
  • TabData (884-887)
🪛 Ruff (0.14.4)
functions/models.py

167-167: zip() without an explicit strict= parameter

Add explicit value for parameter strict=

(B905)

functions/views.py

20-20: Probable use of requests call without timeout

(S113)


80-83: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


88-89: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (11)
daras_ai_v2/icons.py (1)

6-6: LGTM! Clean addition of new icon constant.

The keys icon follows the established pattern and is appropriately used in the account settings UI.

functions/views.py (2)

1-17: LGTM! Type hints improve code clarity.

The addition of type hints and the TYPE_CHECKING block for forward references follows best practices for Python typing.


54-114: LGTM! Well-structured integration authorizations view.

The function correctly:

  • Fetches authorizations from Composio
  • Filters by workspace scope
  • Resolves toolkit names and related entities
  • Renders a clear table with workflow, integration, and scope information
  • Passes current_user for context-aware labeling
routers/account.py (3)

22-22: LGTM! Proper import of new view function.


256-258: LGTM! Title update reflects expanded functionality.

The tab title now appropriately covers both API keys and integration authorizations, using the new icons.keys constant.


378-379: LGTM! Clean integration of the new authorizations UI.

The new section is properly placed and passes the required workspace and user context.

functions/recipe_functions.py (1)

340-346: LGTM! Enables context-aware labeling.

Adding current_user=user to the format_label call allows the scope selector to display personalized labels like "(You)" when appropriate.

functions/composio_tools.py (1)

269-275: LGTM! Clean helper function with sensible fallback.

The function provides a straightforward lookup mechanism and gracefully handles missing toolkits by returning the slug itself.

functions/models.py (3)

86-104: LGTM! Context-aware labeling improves UX.

The addition of the current_user parameter and the updated workspace label logic provide clearer, more personalized scope labels. The distinction between personal and team workspace labeling is well-implemented.


106-114: LGTM! Clear "(You)" indicator for current user.

The logic correctly displays "Only I (FullName)" when the user matches the current user, improving the user experience by making it clear which scopes belong to them.


176-178: LGTM! Useful helper for workspace user_id prefix.

This classmethod provides a clean way to generate the workspace prefix used for filtering authorizations.

Comment on lines +20 to +32
r = requests.get(
"https://backend.composio.dev/api/v3/connected_accounts",
headers={
"x-api-key": str(settings.COMPOSIO_API_KEY),
"Content-Type": "application/json",
"Accept": "application/json",
},
json={
"statuses": ["ACTIVE"],
"limit": 10_000,
},
)
r.raise_for_status()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add timeout to requests.get call.

The HTTP request lacks a timeout parameter, which could cause the application to hang indefinitely if the remote server is unresponsive.

Apply this diff to add a timeout:

 r = requests.get(
     "https://backend.composio.dev/api/v3/connected_accounts",
     headers={
         "x-api-key": str(settings.COMPOSIO_API_KEY),
         "Content-Type": "application/json",
         "Accept": "application/json",
     },
     json={
         "statuses": ["ACTIVE"],
         "limit": 10_000,
     },
+    timeout=30,
 )
🧰 Tools
🪛 Ruff (0.14.4)

20-20: Probable use of requests call without timeout

(S113)

🤖 Prompt for AI Agents
In functions/views.py around lines 20 to 32, the requests.get call is missing a
timeout which can cause the app to hang indefinitely; update the call to include
a timeout parameter (for example timeout=10 or a tuple like timeout=(5, 10) for
connect/read) so the request fails fast on unresponsive servers and propagates
exceptions as before; keep the rest of the headers/json unchanged and ensure any
existing error handling (r.raise_for_status()) continues to work.

Copy link

@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: 2

♻️ Duplicate comments (1)
functions/views.py (1)

20-31: Add timeout to the HTTP request.

This issue was already flagged in the previous review.

🧹 Nitpick comments (1)
functions/views.py (1)

82-94: Consider adding parentheses for clarity.

The and/or operator chaining works correctly but can be harder to read. Adding parentheses makes the precedence explicit.

Apply this diff to improve readability:

 published_runs = (
-    pr_ids
-    and {
+    (pr_ids and {
         pr.published_run_id: pr
         for pr in PublishedRun.objects.filter(published_run_id__in=pr_ids)
-    }
+    })
     or {}
 )
 users = (
-    user_ids
-    and {user.id: user for user in AppUser.objects.filter(id__in=user_ids)}
+    (user_ids and {user.id: user for user in AppUser.objects.filter(id__in=user_ids)})
     or {}
 )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 958a61c and 848fdee.

📒 Files selected for processing (1)
  • functions/views.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
functions/views.py (5)
functions/composio_tools.py (1)
  • get_toolkit_name_by_slug (270-275)
functions/models.py (5)
  • FunctionScopes (40-214)
  • ScopeParts (25-31)
  • get_user_id_for_scope (181-214)
  • from_user_id (160-174)
  • format_label (86-157)
app_users/models.py (1)
  • AppUser (90-262)
bots/models/published_run.py (1)
  • PublishedRun (118-346)
workspaces/models.py (2)
  • Workspace (105-454)
  • html_icon (409-416)
🪛 Ruff (0.14.4)
functions/views.py

20-20: Probable use of requests call without timeout

(S113)


83-87: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


91-92: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


100-100: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)


103-103: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (2)
functions/views.py (2)

1-16: LGTM!

The imports are well-organized, and the TYPE_CHECKING block correctly handles the forward reference to Workspace to avoid circular imports.


54-128: Well-structured integration management UI.

The function efficiently bulk-fetches related objects (published runs and users) to avoid N+1 queries, and the table rendering logic correctly handles various scope types and edge cases.

Comment on lines +36 to +41
workspace_user_id = FunctionScopes.get_user_id_for_scope(
scope=FunctionScopes.workspace,
workspace=workspace,
user=None,
published_run=None,
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Type mismatch: passing None to non-Optional parameters.

Looking at the signature of get_user_id_for_scope in functions/models.py (lines 180-213), the user and published_run parameters are typed as AppUser and PublishedRun without Optional. Passing None violates the type contract, even though it works at runtime for FunctionScopes.workspace scope.

Consider one of these solutions:

Solution 1: Cast to satisfy type checkers:

 workspace_user_id = FunctionScopes.get_user_id_for_scope(
     scope=FunctionScopes.workspace,
     workspace=workspace,
-    user=None,
-    published_run=None,
+    user=typing.cast(AppUser, None),
+    published_run=typing.cast(PublishedRun, None),
 )

Solution 2: Update get_user_id_for_scope signature in functions/models.py to accept Optional types (if you have access to modify it).

📝 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
workspace_user_id = FunctionScopes.get_user_id_for_scope(
scope=FunctionScopes.workspace,
workspace=workspace,
user=None,
published_run=None,
)
workspace_user_id = FunctionScopes.get_user_id_for_scope(
scope=FunctionScopes.workspace,
workspace=workspace,
user=typing.cast(AppUser, None),
published_run=typing.cast(PublishedRun, None),
)

published_run_id and published_runs.get(published_run_id) or None
)
user_id = scope_parts.get(ScopeParts.member)
user = user_id and users.get(int(user_id)) or None
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add error handling for int() conversion.

The int(user_id) conversion could raise a ValueError if user_id contains non-numeric data. While unlikely given the source, defensive programming suggests handling this gracefully.

Apply this diff to handle the conversion safely:

-user = user_id and users.get(int(user_id)) or None
+try:
+    user = (user_id and users.get(int(user_id))) or None
+except (ValueError, TypeError):
+    user = None

Or use a helper:

def safe_int(value):
    try:
        return int(value)
    except (ValueError, TypeError):
        return None

# Then:
user = (user_id and users.get(safe_int(user_id))) or None
🧰 Tools
🪛 Ruff (0.14.4)

103-103: Parenthesize a and b expressions when chaining and and or together, to make the precedence clear

Parenthesize the and subexpression

(RUF021)

🤖 Prompt for AI Agents
In functions/views.py around line 103, the direct int(user_id) conversion can
raise ValueError/TypeError; replace it with a safe conversion and lookup (e.g.,
call a helper safe_int that returns None on invalid input) and use users.get on
the safe result, ensuring user becomes None when conversion fails; update
imports if you add the helper and write tests or checks to cover non-numeric
user_id inputs.

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