Skip to content

Commit 9fbbaa4

Browse files
SK-2813: python sdk v2 code clean up
1 parent 0490e6e commit 9fbbaa4

28 files changed

Lines changed: 1572 additions & 269 deletions

.claude/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See @../AGENTS.md for documentation on how to configure and use Claude agents in this workspace.

.claude/commands/code-review.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
description: Smart code review for the Skyflow Python SDK. Pass "full review" to scan the entire skyflow/ tree, a file/directory path to review that target, or nothing to review files changed on the current branch.
3+
constraints:
4+
- "NEVER edit, create, or delete any file under skyflow/generated/. Filter it out at the git diff step with: git diff --name-only | grep -v 'generated'. If a finding relates to generated code, report it as an observation only."
5+
---
6+
7+
You are a senior engineer reviewing the Skyflow Python SDK — a Python client library for Skyflow's data privacy vault.
8+
9+
## Mode selection — pick exactly one
10+
11+
Inspect `$ARGUMENTS` and choose the review mode:
12+
13+
| Argument | Mode |
14+
|---|---|
15+
| `full review` (case-insensitive) | **Full** — scan all files under `skyflow/` recursively |
16+
| A file or directory path (starts with `/`, `./`, `skyflow/`, `tests/`, `samples/`, etc.) | **Path** — review only that file or directory |
17+
| Empty / anything else | **Branch** — review files changed on the current branch vs `main` |
18+
19+
### Full mode
20+
Scan all files under `skyflow/` recursively, grouped by layer:
21+
```
22+
skyflow/vault/controller/
23+
skyflow/vault/data/
24+
skyflow/vault/tokens/
25+
skyflow/vault/detect/
26+
skyflow/vault/connection/
27+
skyflow/vault/client/
28+
skyflow/utils/validations/
29+
skyflow/utils/
30+
skyflow/service_account/
31+
skyflow/client/
32+
skyflow/error/
33+
skyflow/__init__.py
34+
```
35+
Read each file fully before reporting findings. Work layer by layer — controllers first, then validators, then data models, then utilities.
36+
37+
### Path mode
38+
Restrict the scan to the path given in `$ARGUMENTS` (file or directory). Read every file under that path before reporting.
39+
40+
### Branch mode
41+
Review all files changed on the current branch vs main:
42+
```
43+
git diff main...HEAD --name-only | grep -v 'generated'
44+
git diff main...HEAD
45+
git log main...HEAD --oneline
46+
```
47+
Summarise what the branch does in 2–3 sentences. List files grouped by layer: data models / controllers / validation / service_account / tests / samples / exports / docs.
48+
49+
> **IMPORTANT — Generated code boundary**
50+
> `skyflow/generated/` contains Fern-generated REST client code. **Never modify any file inside `skyflow/generated/`**. If a finding relates to generated code, report it as an observation only — do not edit, create, or delete any file under that path.
51+
52+
---
53+
54+
## What to review
55+
56+
### Basic checks
57+
- Identify issues and unhandled edge cases that can break the code at runtime.
58+
59+
### 1. Request / Response pattern
60+
- Every public operation must use dedicated classes: `XxxRequest`, `XxxResponse`
61+
- Request classes must declare all fields with explicit types (use `Optional[T]` for optional fields, never bare `None` as the sole annotation)
62+
- Response objects must be plain data containers — no business logic, no API calls inside them
63+
- Flag any controller method that accepts or returns plain `dict` instead of a typed class
64+
- Mutable default arguments in `__init__` are a Python footgun — `def __init__(self, items=[])` mutates the class-level list across instances; use `None` and assign in the body instead
65+
66+
### 2. Validation completeness
67+
- Every public controller method must call its `validate_xxx_request()` function from `skyflow/utils/validations/_validations.py` **before** any API call
68+
- Validators must raise `SkyflowError` with an error code from `SkyflowMessages.ErrorCodes`
69+
- Validators must call `log_error_log(SkyflowMessages.ErrorLogs.xxx.value)` before raising
70+
- Check for missing edge cases: `None` inputs, empty strings, wrong types, empty lists, negative numbers
71+
- No truthy guard `if not x:` for values where `0`, `""`, `False`, or `[]` could be intentionally valid — use `x is None` or `x is not None` instead
72+
- Consistent null-guard style across validators in the changed files — no mixing of `if not x`, `if x is None`, `if x == None`
73+
74+
### 3. Error handling
75+
- All methods that call the REST API must be wrapped in `try/except Exception` that calls `handle_exception(e, logger)` or raises `SkyflowError`
76+
- Never swallow errors silently with a bare `except: pass`
77+
- `except` blocks that re-raise must add value (logging, wrapping) — a bare `except Exception as e: raise e` with no added context should be flagged
78+
- `SkyflowError` must be raised with the correct error code for the failure type (INVALID_INPUT for validation, server codes for API failures)
79+
- Bare `except:` (catching `BaseException`) must be replaced with `except Exception:`
80+
81+
### 4. Concurrency and I/O patterns
82+
- File reads must use context managers (`with open(...) as f:`) — never leave file handles open
83+
- `open()` for binary content must use mode `"rb"` not `"r"`
84+
- Blocking I/O (file reads, network calls) inside a loop must be flagged if the loop runs at high volume — suggest batching
85+
- No module-level side effects that execute on import (network calls, file I/O, env reads at import time)
86+
87+
### 5. Python quality
88+
- No mutable default arguments: `def f(x=[])`, `def f(x={})` — use `None` and initialise in the body
89+
- No `from module import *` in non-`__init__.py` files
90+
- No bare `except:` — always catch a specific exception type
91+
- No `global` or `nonlocal` in controller / validator code
92+
- `isinstance()` checks must cover all relevant types — flag `isinstance(x, int)` where `bool` is a subclass of `int` and would be silently accepted when it should not be, or vice versa
93+
- f-strings preferred over `%` formatting and `.format()` for new code; flag inconsistency within the same file
94+
- `Optional[T]` must be imported from `typing` — do not use `T | None` union syntax unless the minimum Python version is ≥ 3.10
95+
96+
### 6. State and side effects
97+
- Controller instances must be stateless per-call — no `self.xxx = <per-call value>` inside method bodies; use local variables instead
98+
- Cached/memoized state (e.g. `_cached_headers`) must not mix per-call and cross-call data
99+
- Class-level variables shared across instances are a source of subtle bugs — flag any mutable class-level variable
100+
101+
### 7. Exports and public API surface
102+
- All public types and classes must be exported from the appropriate `__init__.py`
103+
- Internal helpers (prefixed with `_`) must not appear in `__init__.py` exports
104+
- Circular imports must not exist — flag any `from skyflow.x import y` inside `skyflow/y/__init__.py` that creates a cycle
105+
106+
### 8. Logging
107+
- Use `log_info(message, logger)` for informational messages and `log_error_log(message, logger)` for errors — never `print()` or `logging.xxx()` directly
108+
- Sensitive values (tokens, credentials, private keys, PII) must never appear in log messages or error strings
109+
- Every public method entry and success path must have a corresponding `log_info` call matching the `SkyflowMessages.Info` enum
110+
111+
### 9. Naming conventions (Python)
112+
113+
| Identifier type | Required style | Example |
114+
|---|---|---|
115+
| Variable / parameter / method | `snake_case` | `vault_id`, `token_uri`, `get_records` |
116+
| Constant / module-level value | `UPPER_SNAKE_CASE` | `SKY_META_DATA_HEADER`, `CTX_KEY_REGEX` |
117+
| Class / Exception / Enum | `PascalCase` | `InsertRequest`, `SkyflowError`, `RedactionType` |
118+
| Private method / attribute | `_snake_case` | `_validate_ctx`, `_cached_headers` |
119+
| Source file | `snake_case.py` or `_snake_case.py` for internals | `_file_upload_request.py`, `_validations.py` |
120+
121+
**Acronym rule — all-lowercase in identifiers, not ALL-CAPS:**
122+
- `id` not `ID` (e.g. `skyflow_id`, not `skyflow_ID`)
123+
- `uri` not `URI` (e.g. `token_uri`, not `token_URI`)
124+
- `url` not `URL` (e.g. `callback_url`, not `callback_URL`)
125+
- `api` not `API` (e.g. `api_key`, not `API_key`)
126+
- Exception: class names follow PascalCase title-casing: `SkyflowId`, `TokenUri`; standalone environment variable names follow OS convention (`SKYFLOW_ID`, `TOKEN_URI`)
127+
128+
**What to flag:**
129+
- Any public field, method, or parameter name that uses ALL-CAPS for an acronym in a snake_case context
130+
- Any `camelCase` field or method name in the public API
131+
- Any class, exception, or enum name that is not `PascalCase`
132+
- Any constant that is not `UPPER_SNAKE_CASE`
133+
- Mixed conventions within the same class or module
134+
135+
### 10. Type annotations
136+
- All public method signatures must have parameter type annotations and a return type annotation
137+
- `Any` usage outside `skyflow/generated/` must be justified — flag unannotated parameters that default to implicit `Any`
138+
- `dict` without subscript (`dict` not `dict[str, Any]`) in a public signature must be flagged
139+
- `Optional[T]` parameters must default to `None``def f(x: Optional[str])` without `= None` is a bug
140+
141+
### 11. Function size and complexity
142+
- Flag any function exceeding 50 lines — include the actual line count
143+
- Flag nesting deeper than 3 levels — suggest early returns or extracted helpers
144+
- Flag long `if valid: … entire body …` blocks where an inverted guard + early return would flatten the code
145+
- Flag validator functions that duplicate logic already present in another validator — suggest extracting a shared helper
146+
147+
### 12. Cross-cutting consistency
148+
- All `XxxRequest` classes must declare optional fields with `Optional[T] = None`, not bare `= None`
149+
- All validators must call `log_error_log` before raising `SkyflowError` — flag any that raise directly without logging
150+
- Controller methods must use a consistent call style — flag mixing of direct API calls and `.with_raw_response` within the same controller
151+
- Credential field access must use `CredentialField` constants, not hardcoded strings like `"clientID"` or `"tokenURI"`
152+
153+
---
154+
155+
## Output format
156+
157+
Group findings by file. For each issue:
158+
159+
```
160+
[SEVERITY] file:line — Description
161+
Problem: <what is wrong>
162+
Fix: <concrete suggestion>
163+
```
164+
165+
Severity levels: **CRITICAL** | **BUG** | **EDGE CASE** | **QUALITY**
166+
167+
End with:
168+
169+
**Summary table**
170+
| Severity | Count |
171+
|---|---|
172+
| CRITICAL | n |
173+
| BUG | n |
174+
| EDGE CASE | n |
175+
| QUALITY | n |
176+
| **Total** | n |
177+
178+
**Top 5 highest-priority fixes** (by risk, not count)
179+
180+
**Verdict**: `APPROVE` | `APPROVE WITH FIXES` | `REQUEST CHANGES`
181+
One sentence explaining the verdict.

0 commit comments

Comments
 (0)