Skip to content

Commit b53f329

Browse files
dpageclaude
andcommitted
Fix Python style violations (E501 line length, E122 indentation)
- Fix E501 line-too-long violations across 8 files by wrapping long lines in SQL strings, error messages, docstrings, LLM prompt strings, and test code - Fix E122 continuation line indentation in database.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1b6c7ac commit b53f329

9 files changed

Lines changed: 277 additions & 118 deletions

File tree

web/pgadmin/llm/prompts/explain.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,26 @@
99

1010
"""System prompt for EXPLAIN plan analysis."""
1111

12-
EXPLAIN_ANALYSIS_PROMPT = """You are a PostgreSQL performance expert integrated into pgAdmin 4.
13-
Your task is to analyze EXPLAIN plan output and provide actionable optimization recommendations.
12+
EXPLAIN_ANALYSIS_PROMPT = """You are a PostgreSQL performance
13+
expert integrated into pgAdmin 4.
14+
Your task is to analyze EXPLAIN plan output and provide
15+
actionable optimization recommendations.
1416
1517
## Input Format
1618
1719
You will receive:
18-
1. The EXPLAIN plan output in JSON format (from EXPLAIN (FORMAT JSON, ANALYZE, ...))
20+
1. The EXPLAIN plan output in JSON format
21+
(from EXPLAIN (FORMAT JSON, ANALYZE, ...))
1922
2. The original SQL query that was analyzed
2023
2124
## Analysis Guidelines
2225
2326
1. **Identify Performance Bottlenecks**:
2427
- Sequential scans on large tables (consider if an index would help)
25-
- Nested loops with high row counts (may indicate missing indexes or poor join order)
26-
- Large row estimate variances (actual vs planned) suggesting stale statistics
28+
- Nested loops with high row counts
29+
(may indicate missing indexes or poor join order)
30+
- Large row estimate variances (actual vs planned)
31+
suggesting stale statistics
2732
- Sort operations on large datasets without indexes
2833
- Hash joins spilling to disk (indicated by batch counts > 1)
2934
- High startup costs relative to total costs
@@ -49,7 +54,8 @@
4954
5055
## Response Format
5156
52-
IMPORTANT: Your response MUST be ONLY a valid JSON object with no additional text,
57+
IMPORTANT: Your response MUST be ONLY a valid JSON object
58+
with no additional text,
5359
no markdown formatting, and no code blocks. Return exactly this format:
5460
5561
{
@@ -69,15 +75,17 @@
6975
"sql": "Exact SQL to execute (if applicable, otherwise null)"
7076
}
7177
],
72-
"summary": "One paragraph summary of the overall plan performance and key takeaways"
78+
"summary": "One paragraph summary of the overall
79+
plan performance and key takeaways"
7380
}
7481
7582
Rules:
7683
- Return ONLY the JSON object, nothing before or after it
7784
- Do NOT wrap the JSON in markdown code blocks (no ```)
7885
- Order bottlenecks by severity (high first)
7986
- Order recommendations by priority (1 = highest)
80-
- If the plan looks optimal, return empty bottlenecks array with a positive summary
87+
- If the plan looks optimal, return empty bottlenecks
88+
array with a positive summary
8189
- Always include at least a summary, even for simple plans
8290
- The "sql" field should be null if no SQL action is applicable
8391
"""

web/pgadmin/llm/prompts/nlq.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99

1010
"""System prompt for Natural Language to SQL translation."""
1111

12-
NLQ_SYSTEM_PROMPT = """You are a PostgreSQL SQL expert integrated into pgAdmin 4.
12+
NLQ_SYSTEM_PROMPT = """You are a PostgreSQL SQL expert \
13+
integrated into pgAdmin 4.
1314
Your task is to generate SQL queries based on natural language requests.
1415
1516
You have access to database inspection tools:
1617
- get_database_schema: Get list of schemas, tables, and views in the database
17-
- get_table_info: Get detailed column, constraint, and index information for a table
18-
- execute_sql_query: Run read-only queries to understand data structure (SELECT only)
18+
- get_table_info: Get detailed column, constraint, and \
19+
index information for a table
20+
- execute_sql_query: Run read-only queries to understand \
21+
data structure (SELECT only)
1922
2023
Guidelines:
2124
- Use get_database_schema to discover available tables before writing queries
@@ -31,5 +34,6 @@
3134
Rules:
3235
- Return ONLY the JSON object, nothing else
3336
- No markdown code blocks
34-
- If you need clarification, set "sql" to null and put your question in "explanation"
37+
- If you need clarification, set "sql" to null and put \
38+
your question in "explanation"
3539
"""

web/pgadmin/llm/providers/docker.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ class DockerClient(LLMClient):
5151
which provides an OpenAI-compatible API.
5252
"""
5353

54-
def __init__(self, api_url: Optional[str] = None, model: Optional[str] = None):
54+
def __init__(
55+
self, api_url: Optional[str] = None, model: Optional[str] = None
56+
):
5557
"""
5658
Initialize the Docker Model Runner client.
5759
5860
Args:
59-
api_url: The Docker Model Runner API URL (default: http://localhost:12434).
61+
api_url: The Docker Model Runner API URL
62+
(default: http://localhost:12434).
6063
model: Optional model name. Defaults to ai/qwen3-coder.
6164
"""
6265
self._api_url = (api_url or DEFAULT_API_URL).rstrip('/')
@@ -321,18 +324,26 @@ def _parse_response(self, data: dict) -> LLMResponse:
321324
if stop_reason == StopReason.MAX_TOKENS:
322325
input_tokens = usage.input_tokens
323326
raise LLMClientError(LLMError(
324-
message=f'Response truncated due to token limit '
325-
f'(input: {input_tokens} tokens). '
326-
f'The request is too large for model {self._model}. '
327-
f'Try using a model with a larger context window, '
328-
f'or analyze a smaller scope.',
327+
message=(
328+
f'Response truncated due to token limit '
329+
f'(input: {input_tokens} tokens). '
330+
f'The request is too large for model '
331+
f'{self._model}. '
332+
f'Try using a model with a larger context '
333+
f'window, or analyze a smaller scope.'
334+
),
329335
code='max_tokens',
330336
provider=self.provider_name,
331337
retryable=False
332338
))
333-
elif finish_reason and finish_reason not in ('stop', 'tool_calls'):
339+
elif finish_reason and finish_reason not in (
340+
'stop', 'tool_calls'
341+
):
334342
raise LLMClientError(LLMError(
335-
message=f'Empty response with finish reason: {finish_reason}',
343+
message=(
344+
f'Empty response with finish reason: '
345+
f'{finish_reason}'
346+
),
336347
code=finish_reason,
337348
provider=self.provider_name,
338349
retryable=False

web/pgadmin/llm/providers/openai.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,17 +316,20 @@ def _parse_response(self, data: dict) -> LLMResponse:
316316
raise LLMClientError(LLMError(
317317
message=f'Response truncated due to token limit '
318318
f'(input: {input_tokens} tokens). '
319-
f'The request is too large for model {self._model}. '
320-
f'Try using a model with a larger context window, '
321-
f'or analyze a smaller scope (e.g., a specific schema '
322-
f'instead of the entire database).',
319+
f'The request is too large for model '
320+
f'{self._model}. '
321+
f'Try using a model with a larger context '
322+
f'window, or analyze a smaller scope (e.g., a '
323+
f'specific schema instead of the entire '
324+
f'database).',
323325
code='max_tokens',
324326
provider=self.provider_name,
325327
retryable=False
326328
))
327329
elif finish_reason and finish_reason not in ('stop', 'tool_calls'):
328330
raise LLMClientError(LLMError(
329-
message=f'Empty response with finish reason: {finish_reason}',
331+
message=(f'Empty response with finish reason: '
332+
f'{finish_reason}'),
330333
code=finish_reason,
331334
provider=self.provider_name,
332335
retryable=False

web/pgadmin/llm/reports/pipeline.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ def __init__(
5858
report_type: Type of report ('security', 'performance', 'design').
5959
sections: List of available Section definitions.
6060
client: LLM client for making API calls.
61-
query_executor: Function to execute queries given query_id and context.
61+
query_executor: Function to execute queries given query_id and
62+
context.
6263
max_retries: Maximum retry attempts for rate-limited calls.
6364
retry_base_delay: Base delay in seconds for exponential backoff.
6465
"""
@@ -88,7 +89,9 @@ def execute(self, context: dict) -> str:
8889
if event.get('type') == 'complete':
8990
result = event.get('report', '')
9091
elif event.get('type') == 'error':
91-
raise ReportPipelineError(event.get('message', 'Unknown error'))
92+
raise ReportPipelineError(
93+
event.get('message', 'Unknown error')
94+
)
9295
return result or ''
9396

9497
def execute_with_progress(
@@ -234,7 +237,8 @@ def _planning_stage(self, context: dict) -> list[str]:
234237
if sid in self.sections
235238
]
236239

237-
return valid_ids if valid_ids else [s['id'] for s in available_sections]
240+
return (valid_ids if valid_ids else
241+
[s['id'] for s in available_sections])
238242

239243
except (json.JSONDecodeError, LLMClientError):
240244
# Fallback to all available sections
@@ -312,7 +316,8 @@ def _analyze_section_with_retry(
312316
yield {
313317
'type': 'retry',
314318
'reason': 'rate_limit',
315-
'message': f'Rate limited, retrying in {wait_time}s...',
319+
'message': (f'Rate limited, retrying in '
320+
f'{wait_time}s...'),
316321
'wait_seconds': wait_time
317322
}
318323
time.sleep(wait_time)
@@ -382,15 +387,20 @@ def _synthesize_with_retry(
382387
yield {
383388
'type': 'retry',
384389
'reason': 'rate_limit',
385-
'message': f'Rate limited, retrying in {wait_time}s...',
390+
'message': (f'Rate limited, retrying in '
391+
f'{wait_time}s...'),
386392
'wait_seconds': wait_time
387393
}
388394
time.sleep(wait_time)
389395
else:
390396
# Return partial report with section summaries
391-
partial = "**Note**: Synthesis failed. Section summaries:\n\n"
397+
partial = (
398+
"**Note**: Synthesis failed. Section summaries:\n\n"
399+
)
392400
for r in successful_results:
393-
partial += f"## {r['section_name']}\n\n{r['summary']}\n\n"
401+
partial += (
402+
f"## {r['section_name']}\n\n{r['summary']}\n\n"
403+
)
394404
yield {'type': 'result', 'result': partial}
395405
return
396406

web/pgadmin/llm/reports/prompts.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
# Planning Stage Prompts
1515
# =============================================================================
1616

17-
PLANNING_SYSTEM_PROMPT = """You are a PostgreSQL expert helping to plan a database analysis report.
17+
PLANNING_SYSTEM_PROMPT = """You are a PostgreSQL expert helping to plan a
18+
database analysis report.
1819
19-
Your task is to select which analysis sections are most relevant for the given report type and database context.
20+
Your task is to select which analysis sections are most relevant for the
21+
given report type and database context.
2022
2123
Return ONLY a JSON array of section IDs to analyze, ordered by priority.
2224
Only include sections that are relevant given the database characteristics.
@@ -55,14 +57,16 @@ def get_planning_user_prompt(
5557
- Table count: {context.get('table_count', 'Unknown')}
5658
- Has pg_stat_statements: {context.get('has_stat_statements', False)}
5759
58-
Return a JSON array of section IDs to analyze, e.g.: ["section1", "section2", "section3"]"""
60+
Return a JSON array of section IDs to analyze, e.g.:
61+
["section1", "section2", "section3"]"""
5962

6063

6164
# =============================================================================
6265
# Section Analysis Prompts
6366
# =============================================================================
6467

65-
SECTION_ANALYSIS_SYSTEM_PROMPT = """You are a PostgreSQL expert analyzing database configuration.
68+
SECTION_ANALYSIS_SYSTEM_PROMPT = """You are a PostgreSQL expert analyzing
69+
database configuration.
6670
6771
Analyze the provided data and generate a concise summary (max 300 words).
6872
@@ -111,7 +115,8 @@ def get_section_analysis_prompt(
111115

112116
data_json = json.dumps(data, indent=2, default=str)
113117

114-
return f"""Analyze the following {section_name} data for a PostgreSQL {context.get('server_version', '')} server.
118+
return f"""Analyze the following {section_name} data for a PostgreSQL
119+
{context.get('server_version', '')} server.
115120
116121
Section focus: {section_description}
117122
@@ -130,19 +135,25 @@ def get_section_analysis_prompt(
130135
# Synthesis Prompts
131136
# =============================================================================
132137

133-
SYNTHESIS_SYSTEM_PROMPT = """You are a PostgreSQL expert creating a comprehensive report.
138+
SYNTHESIS_SYSTEM_PROMPT = """You are a PostgreSQL expert creating a
139+
comprehensive report.
134140
135141
Combine the section summaries into a cohesive, well-organized report.
136142
137143
Your report MUST:
138144
1. Start with an **Executive Summary** (3-5 sentences overview)
139-
2. Include a **Critical Issues** section (aggregate all critical/warning findings)
140-
3. Include each section's detailed analysis (use the section content as-is, don't add duplicate headers)
141-
4. End with **Prioritized Recommendations** (numbered list, most important first)
145+
2. Include a **Critical Issues** section (aggregate all critical/warning
146+
findings)
147+
3. Include each section's detailed analysis (use the section content as-is,
148+
don't add duplicate headers)
149+
4. End with **Prioritized Recommendations** (numbered list, most important
150+
first)
142151
143152
IMPORTANT:
144-
- Do NOT include a report title at the very beginning - start directly with Executive Summary
145-
- Each section already has its own ### header - do NOT add extra headers around them
153+
- Do NOT include a report title at the very beginning - start directly with
154+
Executive Summary
155+
- Each section already has its own ### header - do NOT add extra headers
156+
around them
146157
- Simply organize and flow the sections together naturally
147158
148159
Use severity indicators consistently:
@@ -151,7 +162,8 @@ def get_section_analysis_prompt(
151162
- 🟡 Advisory - Consider improving
152163
- 🟢 Good - No issues found
153164
154-
Be professional and actionable. Include SQL commands for recommendations where helpful."""
165+
Be professional and actionable. Include SQL commands for recommendations
166+
where helpful."""
155167

156168

157169
def get_synthesis_prompt(
@@ -186,7 +198,8 @@ def get_synthesis_prompt(
186198
if context.get('schema_name'):
187199
scope_info = f"{context['schema_name']} schema in {scope_info}"
188200

189-
return f"""Create a comprehensive {report_type_display} Report for {scope_info}.
201+
return f"""Create a comprehensive {report_type_display} Report for
202+
{scope_info}.
190203
191204
Server: PostgreSQL {context.get('server_version', 'Unknown')}
192205

0 commit comments

Comments
 (0)