Skip to content

refactor: Move query parameters validation to beartype #1303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 9, 2025

Conversation

whiterabbit1983
Copy link
Contributor

@whiterabbit1983 whiterabbit1983 commented Apr 2, 2025

PR Type

Enhancement, Bug fix, Tests


Description

  • Refactored query parameter validation to use beartype and centralized validation logic.

    • Introduced make_num_validator utility for numeric validation with custom error messages.
    • Added QueryParamsValidationError for consistent exception handling.
  • Replaced inline validation logic in query functions with Annotated and beartype.vale.

  • Enhanced error handling for invalid query parameters across multiple query modules.

  • Added comprehensive test cases for invalid query parameter scenarios.


Changes walkthrough 📝

Relevant files
Enhancement
11 files
validation.py
Added QueryParamsValidationError for query parameter validation errors
+8/-0     
db_exceptions.py
Enhanced exception handling for query parameter validation
+23/-0   
task_validation.py
Removed redundant validation logic for task validation     
+0/-1     
list_agents.py
Refactored query parameter validation for listing agents 
+0/-4     
list_docs.py
Refactored query parameter validation for listing documents
+18/-14 
list_entries.py
Refactored query parameter validation for listing entries
+14/-9   
list_executions.py
Refactored query parameter validation for listing executions
+16/-12 
list_files.py
Refactored query parameter validation for listing files   
+18/-15 
list_tasks.py
Refactored query parameter validation for listing tasks   
+16/-13 
list_users.py
Refactored query parameter validation for listing users   
+14/-9   
utils.py
Added `make_num_validator` utility for numeric validation
+23/-0   
Tests
7 files
test_agent_queries.py
Added tests for invalid query parameters in agent queries
+17/-0   
test_docs_queries.py
Added tests for invalid query parameters in document queries
+194/-0 
test_entry_queries.py
Added tests for invalid query parameters in entry queries
+78/-0   
test_execution_queries.py
Added tests for invalid query parameters in execution queries
+97/-1   
test_files_queries.py
Added tests for invalid query parameters in file queries 
+71/-1   
test_task_queries.py
Added tests for invalid query parameters in task queries 
+74/-0   
test_user_queries.py
Added tests for invalid query parameters in user queries 
+76/-1   

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.

  • Important

    Refactor query parameter validation using beartype across multiple query functions, adding new tests for validation errors.

    • Validation Refactor:
      • Introduced beartype for query parameter validation in functions like list_agents, list_docs, list_entries, list_executions, list_files, list_tasks, and list_users.
      • Removed manual validation checks for limit, offset, sort_by, and direction in these functions.
    • Exceptions:
      • Added QueryParamsValidationError in validation.py for handling query parameter validation errors.
      • Updated common_db_exceptions in db_exceptions.py to map QueryParamsValidationError to HTTP 400 errors.
    • Tests:
      • Added tests for invalid limit, offset, sort_by, and direction parameters in test_agent_queries.py, test_docs_queries.py, test_entry_queries.py, test_execution_queries.py, test_files_queries.py, test_task_queries.py, and test_user_queries.py.

    This description was created by Ellipsis for 757a1da. It will automatically update as commits are pushed.

    Copy link
    Contributor

    CI Feedback 🧐

    A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

    Action: Test

    Failed stage: Run tests [❌]

    Failed test name: task_validation: Task validator detects invalid Python expressions in tasks

    Failure summary:

    The action failed because the test "task_validation: Task validator detects invalid Python
    expressions in tasks" failed. The test is located in the file tests/test_task_validation.py. The
    test expected the task validator to detect invalid Python expressions in tasks, but the validation
    result showed is_valid=True with empty issue lists, indicating it failed to detect the invalid
    expressions that it should have caught.

    Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    1446:  filtering                               
    1447:  PASS  test_agent_metadata_filtering:67 query: list_agents with SQL           3%
    1448:  injection attempt in metadata           
    1449:  filter                                  
    1450:  PASS  test_agent_queries:28 query: create agent sql                          3%
    1451:  PASS  test_agent_queries:44 query: create or update agent sql                4%
    1452:  PASS  test_agent_queries:63 query: update agent sql                          4%
    1453:  PASS  test_agent_queries:90 query: get agent not exists sql                  4%
    1454:  PASS  test_agent_queries:101 query: get agent exists sql                     5%
    1455:  PASS  test_agent_queries:122 query: list agents sql                          5%
    1456:  PASS  test_agent_queries:133 query: list agents sql, invalid sort            5%
    1457:  direction                                         
    1458:  PASS  test_agent_queries:149 query: patch agent sql                          6%
    1459:  PASS  test_agent_queries:173 query: delete agent sql                         6%
    1460:  INFO:httpx:HTTP Request: POST http://testserver/agents "HTTP/1.1 403 Forbidden"
    1461:  PASS  test_agent_routes:9 route: unauthorized should fail                    6%
    1462:  INFO:httpx:HTTP Request: POST http://testserver/agents "HTTP/1.1 201 Created"
    ...
    
    1539:  PASS  test_docs_queries:402 query: delete user doc                          21%
    1540:  PASS  test_docs_queries:439 query: delete agent doc                         21%
    1541:  PASS  test_docs_queries:476 query: search docs by text                      21%
    1542:  PASS  test_docs_queries:513 query: search docs by text with technical       22%
    1543:  terms and phrases                                  
    1544:  PASS  test_docs_queries:576 query: search docs by embedding                 22%
    1545:  PASS  test_docs_queries:604 query: search docs by hybrid                    22%
    1546:  INFO:httpx:HTTP Request: POST http://testserver/users/067ed3e2-ffc5-7b46-8000-15e5c970a183/docs "HTTP/1.1 201 Created"
    1547:  PASS  test_docs_routes:15 route: create user doc                            23%
    1548:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e3-0510-780e-8000-1370fe6d4f4f/docs "HTTP/1.1 201 Created"
    1549:  PASS  test_docs_routes:32 route: create agent doc                           23%
    1550:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e3-0a4e-7633-8000-3d3a828ff28d/docs "HTTP/1.1 201 Created"
    1551:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e3-0a4e-7633-8000-3d3a828ff28d/docs "HTTP/1.1 409 Conflict"
    1552:  INFO:httpx:HTTP Request: POST http://testserver/users/067ed3e3-0dad-735d-8000-213be583fdf2/docs "HTTP/1.1 201 Created"
    1553:  PASS  test_docs_routes:49 route: create agent doc with duplicate title      23%
    1554:  should fail                                          
    1555:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e3-12f0-7a87-8000-7739693e7252/docs "HTTP/1.1 201 Created"
    ...
    
    1634:  PASS  test_execution_queries:136 query: list executions, invalid offset     32%
    1635:  PASS  test_execution_queries:157 query: list executions, invalid sort by    32%
    1636:  PASS  test_execution_queries:178 query: list executions, invalid sort       33%
    1637:  direction                                     
    1638:  PASS  test_execution_queries:199 query: count executions                    33%
    1639:  PASS  test_execution_queries:217 query: create execution transition         33%
    1640:  PASS  test_execution_queries:238 query: create execution transition -       34%
    1641:  validate transition targets                   
    1642:  PASS  test_execution_queries:283 query: create execution transition with    34%
    1643:  execution update                              
    1644:  PASS  test_execution_queries:310 query: get execution with transitions      34%
    1645:  count                                         
    1646:  PASS  test_execution_queries:325 query: list executions with                34%
    1647:  latest_executions view                        
    1648:  PASS  test_execution_queries:348 query: execution with finish transition    35%
    1649:  PASS  test_execution_queries:382 query: execution with error transition     35%
    1650:  SKIP  test_execution_workflow… workflow: evaluate step   needs to be fixed  35%
    1651:  single                                          
    1652:  SKIP  test_execution_workflow… workflow: evaluate step   needs to be fixed  36%
    1653:  multiple                                        
    1654:  SKIP  test_execution_workflo… workflow: variable access  needs to be fixed  36%
    1655:  in expressions                                   
    1656:  SKIP  test_execution_workflo… workflow: yield step       needs to be fixed  36%
    1657:  SKIP  test_execution_workflo… workflow: sleep step       needs to be fixed  37%
    1658:  SKIP  test_execution_workflo… workflow: return step      needs to be fixed  37%
    1659:  direct                                           
    1660:  SKIP  test_execution_workflo… workflow: return step      needs to be fixed  37%
    1661:  nested                                           
    1662:  SKIP  test_execution_workflo… workflow: log step         needs to be fixed  37%
    1663:  SKIP  test_execution_workflo… workflow: log step         needs to be fixed  38%
    1664:  expression fail                                  
    1665:  SKIP  test_execution_workf… workflow: system call   workflow: thread race   38%
    ...
    
    1764:  simple filter                              
    1765:  PASS  test_metadata_filter_utils:37 utility:                                54%
    1766:  build_metadata_filter_conditions with      
    1767:  multiple filters                           
    1768:  PASS  test_metadata_filter_utils:50 utility:                                54%
    1769:  build_metadata_filter_conditions with      
    1770:  table alias                                
    1771:  PASS  test_metadata_filter_utils:66 utility:                                54%
    1772:  build_metadata_filter_conditions with      
    1773:  SQL injection attempts                     
    1774:  PASS  test_mmr:24 utility: test to apply_mmr_to_docs                        54%
    1775:  PASS  test_mmr:61 utility: test mmr with different mmr_strength values      55%
    1776:  PASS  test_mmr:101 utility: test mmr with empty docs list                   55%
    1777:  PASS  test_model_validation:10 validate_model: succeeds when model is       55%
    1778:  available in model list                         
    1779:  PASS  test_model_validation:19 validate_model: fails when model is          56%
    1780:  unavailable in model list                       
    1781:  PASS  test_model_validation:31 validate_model: fails when model is None     56%
    1782:  PASS  test_nlp_utilities:6 utility: clean_keyword                           56%
    ...
    
    1801:  PASS  test_query_utils:5 utility: sanitize_string - strings                 60%
    1802:  PASS  test_query_utils:15 utility: sanitize_string - nested data            61%
    1803:  structures                                           
    1804:  PASS  test_query_utils:41 utility: sanitize_string - non-string types       61%
    1805:  PASS  test_session_queries:37 query: create session sql                     61%
    1806:  PASS  test_session_queries:60 query: create or update session sql           61%
    1807:  PASS  test_session_queries:84 query: get session exists                     62%
    1808:  PASS  test_session_queries:100 query: get session does not exist            62%
    1809:  PASS  test_session_queries:114 query: list sessions                         62%
    1810:  PASS  test_session_queries:131 query: list sessions with filters            63%
    1811:  PASS  test_session_queries:150 query: count sessions                        63%
    1812:  PASS  test_session_queries:164 query: update session sql                    63%
    1813:  PASS  test_session_queries:199 query: patch session sql                     63%
    1814:  PASS  test_session_queries:226 query: delete session sql                    64%
    1815:  INFO:httpx:HTTP Request: GET http://testserver/sessions "HTTP/1.1 403 Forbidden"
    1816:  PASS  test_session_routes:7 route: unauthorized should fail                 64%
    1817:  INFO:httpx:HTTP Request: POST http://testserver/sessions "HTTP/1.1 201 Created"
    ...
    
    1895:  PASS  test_task_queries:70 query: get task sql - exists                     75%
    1896:  PASS  test_task_queries:89 query: get task sql - not exists                 76%
    1897:  PASS  test_task_queries:107 query: delete task sql - exists                 76%
    1898:  PASS  test_task_queries:143 query: delete task sql - not exists             76%
    1899:  PASS  test_task_queries:162 query: list tasks sql - with filters            77%
    1900:  PASS  test_task_queries:183 query: list tasks sql - no filters              77%
    1901:  PASS  test_task_queries:201 query: list tasks sql, invalid limit            77%
    1902:  PASS  test_task_queries:227 query: list tasks sql, invalid offset           77%
    1903:  PASS  test_task_queries:243 query: list tasks sql, invalid sort by          78%
    1904:  PASS  test_task_queries:259 query: list tasks sql, invalid sort direction   78%
    1905:  PASS  test_task_queries:275 query: update task sql - exists                 78%
    1906:  PASS  test_task_queries:311 query: update task sql - not exists             79%
    1907:  PASS  test_task_queries:338 query: patch task sql - exists                  79%
    1908:  PASS  test_task_queries:386 query: patch task sql - not exists              79%
    1909:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e6-b961-7040-8000-7b90c6c2cc71/tasks "HTTP/1.1 403 Forbidden"
    1910:  PASS  test_task_routes:27 route: unauthorized should fail                   79%
    1911:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e6-bccf-7764-8000-2f446afe86a1/tasks "HTTP/1.1 201 Created"
    ...
    
    1921:  INFO:httpx:HTTP Request: GET http://testserver/tasks/067ed3e6-cd5a-787f-8000-48c70a4ae424 "HTTP/1.1 200 OK"
    1922:  PASS  test_task_routes:124 route: get task exists                           81%
    1923:  INFO:httpx:HTTP Request: GET http://testserver/executions/067ed3e6-d7d3-79b3-8000-ceb753e5bd2d/transitions "HTTP/1.1 200 OK"
    1924:  PASS  test_task_routes:134 route: list all execution transition             81%
    1925:  INFO:httpx:HTTP Request: GET http://testserver/executions/067ed3e6-e26f-7823-8000-28255c3da961/transitions/067ed3e6-e5ef-7624-8000-9274788a0ed4 "HTTP/1.1 200 OK"
    1926:  PASS  test_task_routes:149 route: list a single execution transition        82%
    1927:  INFO:httpx:HTTP Request: GET http://testserver/tasks/067ed3e3-b0b1-7870-8000-d6803dc5ce97/executions "HTTP/1.1 200 OK"
    1928:  PASS  test_task_routes:190 route: list task executions                      82%
    1929:  INFO:httpx:HTTP Request: GET http://testserver/agents/067ed3e6-e982-772e-8000-d59dbf4dafdb/tasks "HTTP/1.1 200 OK"
    1930:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e6-e982-772e-8000-d59dbf4dafdb/tasks "HTTP/1.1 201 Created"
    1931:  INFO:httpx:HTTP Request: GET http://testserver/agents/067ed3e6-e982-772e-8000-d59dbf4dafdb/tasks "HTTP/1.1 200 OK"
    1932:  PASS  test_task_routes:205 route: list tasks                                82%
    1933:  SKIP  test_task_routes:248 route: update execution   Temporal connection    83%
    1934:  issue              
    1935:  PASS  test_task_validation:7 task_validation: Python expression validator   83%
    1936:  detects syntax errors                             
    1937:  PASS  test_task_validation:16 task_validation: Python expression validator  83%
    1938:  detects undefined names                          
    1939:  PASS  test_task_validation:25 task_validation: Python expression validator  83%
    1940:  allows steps variable access                     
    1941:  PASS  test_task_validation:33 task_validation: Python expression validator  84%
    1942:  detects unsafe operations                        
    1943:  PASS  test_task_validation:42 task_validation: Python expression validator  84%
    1944:  detects unsafe dunder attributes                 
    1945:  PASS  test_task_validation:63 task_validation: Python expression validator  84%
    1946:  detects potential runtime errors                 
    1947:  PASS  test_task_validation:72 task_validation: Python expression            85%
    ...
    
    1978:  PASS  test_tool_queries:108 query: patch tool                               90%
    1979:  PASS  test_tool_queries:141 query: update tool                              90%
    1980:  PASS  test_user_queries:37 query: create user sql                           90%
    1981:  PASS  test_user_queries:56 query: create or update user sql                 90%
    1982:  PASS  test_user_queries:76 query: update user sql                           91%
    1983:  PASS  test_user_queries:96 query: get user not exists sql                   91%
    1984:  PASS  test_user_queries:112 query: get user exists sql                      91%
    1985:  PASS  test_user_queries:127 query: list users sql                           92%
    1986:  PASS  test_user_queries:142 query: list users sql, invalid limit            92%
    1987:  PASS  test_user_queries:168 query: list users sql, invalid offset           92%
    1988:  PASS  test_user_queries:183 query: list users sql, invalid sort by          92%
    1989:  PASS  test_user_queries:199 query: list users sql, invalid sort direction   93%
    1990:  PASS  test_user_queries:216 query: patch user sql                           93%
    1991:  PASS  test_user_queries:236 query: delete user sql                          93%
    1992:  INFO:httpx:HTTP Request: POST http://testserver/users "HTTP/1.1 403 Forbidden"
    1993:  PASS  test_user_routes:9 route: unauthorized should fail                    94%
    1994:  INFO:httpx:HTTP Request: POST http://testserver/users "HTTP/1.1 201 Created"
    ...
    
    1999:  PASS  test_user_routes:53 route: get user exists                            94%
    2000:  INFO:httpx:HTTP Request: POST http://testserver/users "HTTP/1.1 201 Created"
    2001:  INFO:httpx:HTTP Request: DELETE http://testserver/users/067ed3e7-5c8a-7884-8000-1209b61a5a0a "HTTP/1.1 202 Accepted"
    2002:  INFO:httpx:HTTP Request: GET http://testserver/users/067ed3e7-5c8a-7884-8000-1209b61a5a0a "HTTP/1.1 404 Not Found"
    2003:  PASS  test_user_routes:65 route: delete user                                95%
    2004:  INFO:httpx:HTTP Request: PUT http://testserver/users/067ed3e7-5ffa-75b0-8000-8ed9c0e579d0 "HTTP/1.1 200 OK"
    2005:  INFO:httpx:HTTP Request: GET http://testserver/users/067ed3e7-5ffa-75b0-8000-8ed9c0e579d0 "HTTP/1.1 200 OK"
    2006:  PASS  test_user_routes:94 route: update user                                95%
    2007:  INFO:httpx:HTTP Request: PATCH http://testserver/users/067ed3e7-6407-771a-8000-d168c799dace "HTTP/1.1 200 OK"
    2008:  INFO:httpx:HTTP Request: GET http://testserver/users/067ed3e7-6407-771a-8000-d168c799dace "HTTP/1.1 200 OK"
    2009:  PASS  test_user_routes:124 query: patch user                                95%
    2010:  INFO:httpx:HTTP Request: GET http://testserver/users "HTTP/1.1 200 OK"
    2011:  PASS  test_user_routes:155 query: list users                                96%
    2012:  INFO:httpx:HTTP Request: GET http://testserver/users?metadata_filter=%7B%27test%27%3A+%27test%27%7D "HTTP/1.1 200 OK"
    2013:  PASS  test_user_routes:170 query: list users with right metadata filter     96%
    2014:  PASS  test_validation_errors:9 format_location: formats error location      96%
    2015:  paths correctly                                 
    2016:  PASS  test_validation_errors:31 get_error_suggestions: generates helpful    97%
    2017:  suggestions for missing fields                 
    2018:  PASS  test_validation_errors:42 get_error_suggestions: generates helpful    97%
    2019:  suggestions for type errors                    
    2020:  PASS  test_validation_errors:64 get_error_suggestions: generates helpful    97%
    2021:  suggestions for string length errors           
    2022:  PASS  test_validation_errors:85 get_error_suggestions: generates helpful    97%
    2023:  suggestions for number range errors            
    2024:  WARNING:agents_api.web:Validation error: [{'type': 'dict_type', 'msg': 'Input should be a valid dictionary', 'loc': 'metadata', 'received': 'not-an-object'}, {'type': 'missing', 'msg': 'Field required', 'loc': 'name', 'fix': 'Add this required field to your request', 'example': '{ "field_name": "value" }', 'received': "{'about': 'Test agent description', 'model': 'invalid-model-id', 'metadata': 'not-an-object'}"}]
    2025:  INFO:httpx:HTTP Request: POST http://testserver/agents "HTTP/1.1 422 Unprocessable Entity"
    2026:  PASS  test_validation_errors:107 validation_error_handler: returns          98%
    2027:  formatted error response for validation       
    2028:  errors                                        
    2029:  PASS  test_validation_errors:148 validation_error_suggestions: function     98%
    2030:  generates helpful suggestions for all         
    2031:  error types                                   
    2032:  PASS  test_workflow_helpers:25 execute_map_reduce_step_parallel:            98%
    ...
    
    2041:  INFO:httpx:HTTP Request: POST http://testserver/tasks/067ed3e7-6bd9-7dde-8000-a3be93240a91/executions "HTTP/1.1 201 Created"
    2042:  PASS  test_workflow_routes:10 workflow route: evaluate step single          99%
    2043:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e7-7133-78e3-8000-58a027f56289/tasks "HTTP/1.1 201 Created"
    2044:  INFO:httpx:HTTP Request: POST http://testserver/tasks/067ed3e7-7338-7c4e-8000-165779e84d7a/executions "HTTP/1.1 201 Created"
    2045:  PASS  test_workflow_routes:41 workflow route: evaluate step single with     99%
    2046:  yaml                                             
    2047:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e7-76b8-7426-8000-a029e20c2cce/tasks "HTTP/1.1 201 Created"
    2048:  INFO:httpx:HTTP Request: POST http://testserver/tasks/067ed3e7-78c7-7453-8000-4c5168425dfb/executions "HTTP/1.1 201 Created"
    2049:  PASS  test_workflow_routes:83 workflow route: evaluate step single with    100%
    2050:  yaml - nested                                    
    2051:  INFO:httpx:HTTP Request: POST http://testserver/agents/067ed3e7-7c50-76b5-8000-deeaa2deb296/tasks/067ed3e7-7c8b-7ff1-8000-e8df1f149d86 "HTTP/1.1 201 Created"
    2052:  INFO:httpx:HTTP Request: POST http://testserver/tasks/067ed3e7-7c8b-7ff1-8000-e8df1f149d86/executions "HTTP/1.1 201 Created"
    2053:  PASS  test_workflow_routes:128 workflow route: create or update: evaluate  100%
    2054:  step single with yaml                           
    2055:  ─ task_validation: Task validator detects invalid Python expressions in tasks ──
    2056:  Failed at tests/test_task_validation.py                                       
    2057:  ╭─────────────────── Traceback (most recent call last) ────────────────────╮  
    ...
    
    2093:  │ │                     │   │   )                                        │ │  
    2094:  │ │                     │   ],                                           │ │  
    2095:  │ │                     │   input_schema=None,                           │ │  
    2096:  │ │                     │   tools=[],                                    │ │  
    2097:  │ │                     │   inherit_tools=True,                          │ │  
    2098:  │ │                     │   metadata=None                                │ │  
    2099:  │ │                     )                                                │ │  
    2100:  │ │ validation_result = TaskValidationResult(                            │ │  
    2101:  │ │                     │   is_valid=True,                               │ │  
    2102:  │ │                     │   python_expression_issues=[],                 │ │  
    2103:  │ │                     │   schema_issues=[],                            │ │  
    2104:  │ │                     │   other_issues=[]                              │ │  
    2105:  │ │                     )                                                │ │  
    2106:  │ ╰──────────────────────────────────────────────────────────────────────╯ │  
    2107:  ╰──────────────────────────────────────────────────────────────────────────╯  
    2108:  AssertionError                                                                
    2109:  ────────────────────────────────────────────────────────────────────────────────
    2110:  ╭───────────── Results ─────────────╮
    2111:  │  345  Tests Encountered           │
    2112:  │  315  Passes             (91.3%)  │
    2113:  │    1  Failures           (0.3%)   │
    2114:  │   29  Skips              (8.4%)   │
    2115:  ╰───────────────────────────────────╯
    2116:  ─────────────────────────── FAILED in 189.69 seconds ───────────────────────────
    2117:  sys:1: RuntimeWarning: coroutine '_.<locals>._resp' was never awaited
    2118:  RuntimeWarning: Enable tracemalloc to get the object allocation traceback
    2119:  ##[error]Process completed with exit code 1.
    2120:  Post job cleanup.
    

    @whiterabbit1983 whiterabbit1983 force-pushed the r/refactor-query-params-validation branch from d92f538 to 757a1da Compare April 8, 2025 08:20
    @whiterabbit1983 whiterabbit1983 marked this pull request as ready for review April 8, 2025 08:21
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Exception Handling

    The new exception handlers for BeartypeCallHintParamViolation use string matching on error messages which could be fragile if beartype's error format changes.

    lambda e: isinstance(e, BeartypeCallHintParamViolation)
    and "typing.Literal['asc', 'desc']" in str(e): partialclass(
        HTTPException,
        status_code=400,
        detail="Invalid sort direction",
    ),
    lambda e: isinstance(e, BeartypeCallHintParamViolation)
    and (
        "typing.Literal['created_at', 'updated_at']" in str(e)
        or "typing.Literal['created_at', 'timestamp']" in str(e)
    ): partialclass(
        HTTPException,
        status_code=400,
        detail="Invalid sort field",
    ),
    Commented Code

    There are commented out validation checks that should be removed since they're now handled by beartype validation.

    # if direction.lower() not in ["asc", "desc"]:
    #     raise HTTPException(status_code=400, detail="Invalid sort direction")
    
    # if sort_by not in ["created_at", "updated_at"]:
    #     raise HTTPException(status_code=400, detail="Invalid sort field")

    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Remove commented validation code

    Remove commented-out code that's no longer needed since validation is now
    handled by beartype. Commented code creates maintenance confusion and clutters
    the codebase.

    agents-api/agents_api/queries/docs/list_docs.py [100-104]

    -# if direction.lower() not in ["asc", "desc"]:
    -#     raise HTTPException(status_code=400, detail="Invalid sort direction")
    +# Validation now handled by beartype annotations
     
    -# if sort_by not in ["created_at", "updated_at"]:
    -#     raise HTTPException(status_code=400, detail="Invalid sort field")
    -
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    __

    Why: The commented-out code is now redundant since validation is handled by beartype annotations. Removing this commented code improves code readability and maintainability by eliminating confusion about which validation approach is actually being used.

    Medium
    • More

    Copy link
    Contributor

    @ellipsis-dev ellipsis-dev bot left a comment

    Choose a reason for hiding this comment

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

    ❌ Changes requested. Reviewed everything up to 757a1da in 2 minutes and 25 seconds

    More details
    • Looked at 1211 lines of code in 18 files
    • Skipped 0 files when reviewing.
    • Skipped posting 11 drafted comments based on config settings.
    1. agents-api/tests/test_user_queries.py:104
    • Draft comment:
      Consider using raises(HTTPException) (or a more specific exception type) instead of the generic Exception in this test for consistency and clearer error expectations.
    • Reason this comment was not posted:
      Comment was not on a location in the diff, so it can't be submitted as a review comment.
    2. agents-api/agents_api/common/exceptions/validation.py:4
    • Draft comment:
      New exception class QueryParamsValidationError is implemented clearly. Consider adding additional context or attributes if needed in the future.
    • Reason this comment was not posted:
      Confidence changes required: 0% <= threshold 50%
      None
    3. agents-api/agents_api/common/utils/db_exceptions.py:191
    • Draft comment:
      The lambda mapping checking for BeartypeCallHintParamViolation relies on string matching (e.g. 'typing.Literal['asc', "desc"]') which is brittle. Consider using error attributes or a more robust method for detecting invalid sort parameters.
    • Reason this comment was not posted:
      Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50%
      While string matching error messages can be fragile, I need to consider: 1) Is there actually a better way to handle this? 2) BeartypeCallHintParamViolation may not expose the literal type information in a more structured way 3) The strings being matched are type hints which are unlikely to change frequently 4) The comment doesn't provide a concrete alternative solution.
      I may be underestimating the maintenance burden of string matching. The error format could change in future beartype versions.
      Without a concrete better alternative suggested, and given these are Python type hints that are relatively stable, the current approach seems reasonable even if not perfect.
      The comment raises a valid concern but doesn't provide an actionable alternative. The current implementation, while not ideal, is pragmatic given the constraints.
    4. agents-api/agents_api/queries/agents/list_agents.py:70
    • Draft comment:
      Remove commented-out explicit sort direction validation. The refactor uses beartype to enforce valid parameters, so this obsolete code should be removed.
    • Reason this comment was not posted:
      Comment was not on a location in the diff, so it can't be submitted as a review comment.
    5. agents-api/agents_api/queries/executions/list_executions.py:106
    • Draft comment:
      Remove the commented-out HTTPException check for sort field. Rely on type validation via beartype instead of manual checks.
    • Reason this comment was not posted:
      Marked as duplicate.
    6. agents-api/agents_api/queries/files/list_files.py:61
    • Draft comment:
      Remove the commented-out validations for sort direction and field in list_files. The new approach using Annotated and beartype.vale makes these manual checks unnecessary.
    • Reason this comment was not posted:
      Marked as duplicate.
    7. agents-api/agents_api/queries/tasks/list_tasks.py:85
    • Draft comment:
      Remove the commented-out validations for sort direction, limit, and offset in the list_tasks query; the new beartype-based validation handles these checks.
    • Reason this comment was not posted:
      Marked as duplicate.
    8. agents-api/agents_api/queries/utils.py:387
    • Draft comment:
      In the make_num_validator function, using 'nonlocal err_msg' to reassign the error message may be error-prone if the validator is reused. Ensure that the err_msg remains consistent and is not inadvertently modified on subsequent validations.
    • Reason this comment was not posted:
      Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50%
      The comment raises a theoretical concern about reuse of the validator, but looking at the implementation: 1) The err_msg is only modified if it's None 2) Each call to make_num_validator creates a new closure with its own err_msg 3) The modification is intentional to provide default messages 4) The current implementation is actually a common and valid pattern for default values.
      I could be wrong about the closure behavior. There might be edge cases where reusing the same validator instance could cause issues.
      The closure creates a new scope each time make_num_validator is called, so each validator instance has its own independent err_msg. The modification is intentional for providing defaults.
      The comment should be deleted because it raises a theoretical concern about a pattern that is actually correct and commonly used for providing default error messages.
    9. agents-api/agents_api/queries/utils.py:86
    • Draft comment:
      It looks like the function definition for pg_query is written as def pg_query[**P](. The use of square brackets here seems unusual for declaring a generic function in Python. Please verify if this syntax is intentional, or if it should be rewritten with standard generic syntax (e.g., using type variables or without the brackets).
    • Reason this comment was not posted:
      Comment was not on a location in the diff, so it can't be submitted as a review comment.
    10. agents-api/agents_api/queries/utils.py:340
    • Draft comment:
      In the function sanitize_string, the isinstance check on line 340 uses if isinstance(data, list | tuple):. While the union operator is allowed in type annotations, for isinstance it should be a tuple of types. This should be updated to if isinstance(data, (list, tuple)): for correct behavior.
    • Reason this comment was not posted:
      Comment was not on a location in the diff, so it can't be submitted as a review comment.
    11. agents-api/tests/test_files_queries.py:1
    • Draft comment:
      The header comment on line 1 reads "Tests for entry queries", which appears inconsistent with the file's purpose of testing file queries. Consider updating this comment to reflect that these tests are for file queries, e.g., "Tests for file queries".
    • Reason this comment was not posted:
      Comment was not on a location in the diff, so it can't be submitted as a review comment.

    Workflow ID: wflow_e8c3OZpfCuWFM8HF


    Want Ellipsis to fix these issues? Tag @ellipsis-dev in a comment. You can customize Ellipsis with 👍 / 👎 feedback, review rules, user-specific overrides, quiet mode, and more.

    @@ -87,17 +97,11 @@ async def list_docs(
    Raises:
    HTTPException: If invalid parameters are provided.
    """
    if direction.lower() not in ["asc", "desc"]:
    raise HTTPException(status_code=400, detail="Invalid sort direction")
    # if direction.lower() not in ["asc", "desc"]:
    Copy link
    Contributor

    Choose a reason for hiding this comment

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

    Remove the commented-out HTTPException checks for sort direction and sort field. With the new beartype validators in place, these checks are redundant.

    @creatorrr creatorrr merged commit f6fb944 into dev Apr 9, 2025
    14 checks passed
    @creatorrr creatorrr deleted the r/refactor-query-params-validation branch April 9, 2025 05:13
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    2 participants