-
Notifications
You must be signed in to change notification settings - Fork 10.2k
Practical #146
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
base: main
Are you sure you want to change the base?
Practical #146
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,141 @@ | ||||||||||||||||||||||
| import json | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import requests | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| try: | ||||||||||||||||||||||
| import brotli | ||||||||||||||||||||||
| except ImportError: # pragma: no cover - optional dependency | ||||||||||||||||||||||
| brotli = None | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| URL = "https://chartink.com/screener/process" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| HEADERS = { | ||||||||||||||||||||||
| "accept": "*/*", | ||||||||||||||||||||||
| "accept-encoding": "gzip, deflate, br, zstd", | ||||||||||||||||||||||
| "accept-language": "en-GB,en-US;q=0.9,en;q=0.8", | ||||||||||||||||||||||
| "content-type": "application/json", | ||||||||||||||||||||||
| "origin": "https://chartink.com", | ||||||||||||||||||||||
| "priority": "u=1, i", | ||||||||||||||||||||||
| "referer": "https://chartink.com/screener/copy-rsi-above-55-and-breakout-615", | ||||||||||||||||||||||
| "sec-ch-ua": '"Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"', | ||||||||||||||||||||||
| "sec-ch-ua-mobile": "?0", | ||||||||||||||||||||||
| "sec-ch-ua-platform": '"macOS"', | ||||||||||||||||||||||
| "sec-fetch-dest": "empty", | ||||||||||||||||||||||
| "sec-fetch-mode": "cors", | ||||||||||||||||||||||
| "sec-fetch-site": "same-origin", | ||||||||||||||||||||||
| "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36", | ||||||||||||||||||||||
| "x-requested-with": "XMLHttpRequest", | ||||||||||||||||||||||
| "x-xsrf-token": "eyJpdiI6IkVhTE9nVThwZk1aY0ppQWFDMVFKOGc9PSIsInZhbHVlIjoiZ1MxQUdZL2NCYzJHWHFQelZJTElqSVFWWlBnclBZYzZ5YW9CdTRQRkRNOXZ0bmpxZHhnOWIzQ3piYXBGZkRQQVpIQU4rL2lnakFmT1YxVzJRWHRzUzlmYUJBMWtTZUxNVXc1aVg1a3M3czBwZTFmbzRQUXJvY3ZOY0gwSHZOV1AiLCJtYWMiOiJjNjhlZTJkZTg4ZmE4NDAzZDljOWQ2MjJhMjQxMzM4OGUxNzMzODU5NjM4MGVkODE4YWJmNTg2Zjg1YjAxNzJiIiwidGFnIjoiIn0=", | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| cookie_header = ( | ||||||||||||||||||||||
| "remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6IkhDd05qM2pTT1JVZW0vdGVHOWNQYlE9PSIsInZhbHVlIjoiNWpJVlIzdW8vRnpWemJGWW80ZWVKelBQUmJqSUZiNy9MWW1HbXk5UEFTa2RWaEJFekNxY0F2bHRpc3M0S2hOR0JGQU5pbzZYNityTURhTGJrT25RcHVNQjR3N2dnNTNWRnhwV1o5QlNnT1ZVYlh4UWgrMWNuYlprM2VMR0tTZmoxczdRRXNFMnIzMndsaUp4MWp1bU00d0tKK3FyNnlhdDgyaytXdmZhUm91NGtLa25JcDYwYkIzTCs5M0Y0VDZnUk92ZWdVQytya0JIdkx1RGlsS1hZdzlUMEJ5RGJXSjZqb0Y3YytwK2V3VT0iLCJtYWMiOiJhOGZiOGY1ZDFiYmExNDRhNmVhMjRmZmExN2FmOGI1Y2VjMDYwZDNkNzZkOGMyOGIzYmM0OWU3M2VkZGEzZWY3IiwidGFnIjoiIn0%3D; _cc_id=ddd4893ce0c7883fd0816bb00b1dd02a; FCCDCF=%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2C%5B%5B32%2C%22%5B%5C%226f1b27a0-7d11-4a14-98ae-03a35fed3e2a%5C%22%2C%5B1784555417%2C262000000%5D%5D%22%5D%5D%5D; FCNEC=%5B%5B%22AKsRol-TAHbJACJY4lTrE5ZSlvrKAxjPJXn5e-ns2BOn-gqwuibhr6NbHGZUaZzRF80Ca7kNMBb7QAhsRqSehMMwoudMOCcEK5KcwrhEfRWcCXflfJ6qWQ5mePeAXNlA69Fav4cxcIwmIYxtne0C09Q3gSkT2v11bg%3D%3D%22%5D%5D; __utma=102564947.1968319544.1784554512.1784685434.1784685434.1; __utmz=102564947.1784685434.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _gid=GA1.2.1711244705.1785667224; _ga=GA1.1.1968319544.1784554512; XSRF-TOKEN=eyJpdiI6IkVhTE9nVThwZk1aY0ppQWFDMVFKOGc9PSIsInZhbHVlIjoiZ1MxQUdZL2NCYzJHWHFQelZJTElqSVFWWlBnclBZYzZ5YW9CdTRQRkRNOXZ0bmpxZHhnOWIzQ3piYXBGZkRQQVpIQU4rL2lnakFmT1YxVzJRWHRzUzlmYUJBMWtTZUxNVXc1aVg1a3M3czBwZTFmbzRQUXJvY3ZOY0gwSHZOV1AiLCJtYWMiOiJjNjhlZTJkZTg4ZmE4NDAzZDljOWQ2MjJhMjQxMzM4OGUxNzMzODU5NjM4MGVkODE4YWJmNTg2Zjg1YjAxNzJiIiwidGFnIjoiIn0%3D; ci_session=eyJpdiI6IkY1c09MOXdNc2JPcTZSUlRKNUNSS0E9PSIsInZhbHVlIjoiYjI0dG84dXNpTzV2czladlhSWC9qZmdEa0Ixa3JxTTRXTmU4QStEdUZTNmU5UURyYmpqbkk5VjREb0tYbUxTcE5NcEdXa09pdTdCQVQ1Qy9wMkIzNVgvQlMwU1Z6eEZHbmJDbXRBek1vREQ3RHF4VGs1U2hpMFJYaHlsNmdTZ2giLCJtYWMiOiIyNzZiYzMzNGRjOTlkYTJmNjZkN2Q5YzYyYWRmMTUyMGZhMWYwMDA1ZTQ3M2FhYmYxNzEwZmI5NjAzNWY5NjE4IiwidGFnIjoiIn0%3D; __gads=ID=a475dc11d13edfcf:T=1784555440:RT=1785667724:S=ALNI_MYui5MgqrqdpMh-ReKIEte6_hI-uA; __gpi=UID=000014cd24fad536:T=1784555440:RT=1785667724:S=ALNI_MZGgCFV-utYaaRCbqopFGIu-JkQow; __eoi=ID=262f680056f8b3e7:T=1784555440:RT=1785667724:S=AA-Afja56EFTSdPZv4hb308AWKUH; _ga_7P3KPC3ZPP=GS2.1.s1785665055$o7$g1$t1785667725$j33$l0$h0" | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| HEADERS["cookie"] = cookie_header | ||||||||||||||||||||||
|
Comment on lines
+28
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win Remove the committed session credentials. Line 28 embeds an XSRF token. Lines 31-35 embed Revoke the exposed sessions and tokens. Remove these values from the repository and its history. Load required credentials from a local secret store or environment variables. 🧰 Tools🪛 Betterleaks (1.7.0)[high] 28-28: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) [high] 32-32: Detected a Generic API Key, potentially exposing access to various services and sensitive operations. (generic-api-key) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| COOKIES = {} | ||||||||||||||||||||||
| for raw_cookie in cookie_header.split(";"): | ||||||||||||||||||||||
| if "=" in raw_cookie: | ||||||||||||||||||||||
| key, value = raw_cookie.split("=", 1) | ||||||||||||||||||||||
| COOKIES[key.strip()] = value.strip() | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| PAYLOADS = { | ||||||||||||||||||||||
| "RSIAbove50": { | ||||||||||||||||||||||
| "scan_clause": "( {cash} ( weekly close >= 52 and daily ema( close,5 ) > daily ema( close,26 ) and daily ema( close,13 ) > daily ema( close,26 ) and daily close > 1 day ago close * 1.03 and daily volume > daily sma( volume,20 ) * 1.0 and daily ema( close,5 ) > daily ema( close,13 ) and daily high = daily max( 260 , daily high ) * 1 and 1 day ago close > 2 days ago close * 0.98 and daily rsi( 14 ) > 55 ) )", | ||||||||||||||||||||||
| "debug_clause": "groupcount( 1 where weekly close >= 52),groupcount( 1 where daily ema( close,5 ) > daily ema( close,26 )),groupcount( 1 where daily ema( close,13 ) > daily ema( close,26 )),groupcount( 1 where daily close > 1 day ago close * 1.03),groupcount( 1 where daily volume > daily sma( volume,20 ) * 1.0),groupcount( 1 where daily ema( close,5 ) > daily ema( close,13 )),groupcount( 1 where daily high = daily max( 260 , daily high ) * 1),groupcount( 1 where 1 day ago close > 2 days ago close * 0.98),groupcount( 1 where daily rsi( 14 ) > 55)", | ||||||||||||||||||||||
| "column_clause": " Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'", | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "ShortTermBreakouts": { | ||||||||||||||||||||||
| "scan_clause": "( {cash} ( daily max( 5 , daily close ) > 6 days ago max( 120 , daily close ) * 1.05 and daily volume > daily sma( volume,5 ) and daily close > 1 day ago close ) )", | ||||||||||||||||||||||
| "debug_clause": "groupcount( 1 where daily max( 5 , daily close ) > 6 days ago max( 120 , daily close ) * 1.05),groupcount( 1 where daily volume > daily sma( volume,5 )),groupcount( 1 where daily close > 1 day ago close)", | ||||||||||||||||||||||
| "column_clause": " Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily \"close - 1 candle ago close / 1 candle ago close * 100\" > 0,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'", | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "52wHighBreakouts": { | ||||||||||||||||||||||
| "scan_clause":"( {cash} ( daily close > 1 day ago max( 240 , daily high ) ) )","debug_clause":"groupcount( 1 where daily close > 1 day ago max( 240 , daily high ))","column_clause":" Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "Dr J VIP daily Breakout scanner": { | ||||||||||||||||||||||
| "scan_clause":"( {cash} ( ( {cash} ( daily volume > 10000 and monthly close > 100 and( {cash} ( daily close >= 1 day ago max( 10 , daily high ) * 1.02 or daily close >= 1 day ago max( 20 , daily high ) * 1.02 or daily close >= 1 day ago max( 30 , daily high ) * 1.02 or daily close >= 1 day ago max( 40 , daily high ) * 1.02 or daily close >= 1 day ago max( 50 , daily high ) * 1.02 or daily close >= 1 day ago max( 60 , daily high ) * 1.02 or daily close >= 1 day ago max( 70 , daily high ) * 1.02 or daily close >= 1 day ago max( 80 , daily high ) * 1.02 or daily close >= 1 day ago max( 90 , daily high ) * 1.02 or daily close >= 1 day ago max( 100 , daily high ) * 1.02 or daily close >= 1 day ago max( 110 , daily high ) * 1.02 or daily close >= 1 day ago max( 120 , daily high ) * 1.02 or daily close >= 1 day ago max( 130 , daily high ) * 1.02 or daily close >= 1 day ago max( 140 , daily high ) * 1.02 or daily close >= 1 day ago max( 150 , daily high ) * 1.02 or daily close >= 1 day ago max( 160 , daily high ) * 1.02 or daily close >= 1 day ago max( 170 , daily high ) * 1.02 or daily close >= 1 day ago max( 180 , daily high ) * 1.02 or daily close >= 1 day ago max( 190 , daily high ) * 1.02 or daily close >= 1 day ago max( 200 , daily high ) * 1.02 ) ) and yearly debt equity ratio < 1 and quarterly foreign institutional investors percentage > 0.5 and market cap > 500 and quarterly mutual funds or uti percentage > 0.5 ) ) ) )","debug_clause":"groupcount( 1 where daily volume > 10000),groupcount( 1 where monthly close > 100),groupcount( 1 where daily close >= 1 day ago max( 10 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 20 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 30 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 40 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 50 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 60 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 70 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 80 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 90 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 100 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 110 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 120 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 130 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 140 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 150 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 160 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 170 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 180 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 190 , daily high ) * 1.02),groupcount( 1 where daily close >= 1 day ago max( 200 , daily high ) * 1.02),groupcount( 1 where yearly debt equity ratio < 1),groupcount( 1 where quarterly foreign institutional investors percentage > 0.5),groupcount( 1 where market cap > 500),groupcount( 1 where quarterly mutual funds or uti percentage > 0.5)","column_clause":" Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "Volume Shockers":{ | ||||||||||||||||||||||
| "scan_clause":"( {cash} ( daily volume > daily sma( volume,20 ) * 5 ) )","debug_clause":"groupcount( 1 where daily volume > daily sma( volume,20 ) * 5)","column_clause":" Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "15min Breakout":{"scan_clause":"( {cash} ( ( {cash} ( [0] 15 minute close > [0] 15 minute max( 6 , [-1] 15 minute high ) or [0] 15 minute close < [0] 15 minute min( 6 , [-1] 15 minute low ) ) ) and( {cash} ( [0] 15 minute close > [0] 15 minute supertrend( 9,2 ) or [0] 15 minute close > [0] 15 minute supertrend( 9,2 ) and [ -1 ] 15 minute close <= [ -1 ] 15 minute supertrend( 9,2 ) ) ) and( {cash} ( [0] 15 minute macd line( 26,12,9 ) > [0] 15 minute macd signal( 26,12,9 ) and daily volume > 300000 and daily close > 500 ) ) ) )","debug_clause":"groupcount( 1 where [0] 15 minute close > [0] 15 minute max( 6 , [-1] 15 minute high )),groupcount( 1 where [0] 15 minute close < [0] 15 minute min( 6 , [-1] 15 minute low )),groupcount( 1 where [0] 15 minute close > [0] 15 minute supertrend( 9,2 )),groupcount( 1 where [0] 15 minute close > [0] 15 minute supertrend( 9,2 ) and [ -1 ] 15 minute close <= [ -1 ] 15 minute supertrend( 9,2 )),groupcount( 1 where [0] 15 minute macd line( 26,12,9 ) > [0] 15 minute macd signal( 26,12,9 )),groupcount( 1 where daily volume > 300000),groupcount( 1 where daily close > 500)","column_clause":" Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| "Potential Breakouts":{"scan_clause":"( {cash} ( daily close * 1.05 > daily max( 200 , daily high ) and daily max( 30 , daily high ) <= 30 days ago max( 8 , daily high ) and daily volume > daily sma( daily volume , 50 ) and daily close > 90 ) )","debug_clause":"groupcount( 1 where daily close * 1.05 > daily max( 200 , daily high )),groupcount( 1 where daily max( 30 , daily high ) <= 30 days ago max( 8 , daily high )),groupcount( 1 where daily volume > daily sma( daily volume , 50 )),groupcount( 1 where daily close > 90)","column_clause":" Daily Close as 'scan-column-default-close', Daily \"close - 1 candle ago close / 1 candle ago close * 100\" as 'scan-column-default-percent-change', filternumber( daily close > 1 day ago close,1) as 'default-percent-change-conditional-filters-color', Daily Volume as 'scan-column-default-volume'" | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| aggregated_rows = {} | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for tag, payload in PAYLOADS.items(): | ||||||||||||||||||||||
| response = requests.post(URL, headers=HEADERS, cookies=COOKIES, json=payload, timeout=30) | ||||||||||||||||||||||
| print(f"\nTag: {tag} | Status code: {response.status_code}") | ||||||||||||||||||||||
|
Comment on lines
+72
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Locate file:"
fd -a 'screener-integration.py' . || true
file="$(fd 'screener-integration.py' . | head -n1 || true)"
if [ -n "${file:-}" ]; then
echo "File: $file"
wc -l "$file"
echo "--- outline ---"
ast-grep outline "$file" || true
echo "--- relevant lines 1-140 ---"
sed -n '1,140p' "$file" | nl -ba
fi
echo "Search for exception handling around requests.post:"
rg -n "requests\.post|RequestException|except .*Exception|PAYLOADS|for tag" . || true
echo "Git diff stat/name:"
git diff --stat || true
git diff -- "$file" | sed -n '1,220p' || trueRepository: iam-veeramalla/python-for-devops Length of output: 1574 🏁 Script executed: #!/bin/bash
set -euo pipefail
file="$(fd 'screener-integration.py' . | head -n1 || true)"
if [ -n "${file:-}" ]; then
python3 - <<'PY' "$file"
import ast, sys
path=sys.argv[1]
with open(path, 'rb') as f:
tree=ast.parse(f.read(), filename=path, type_comments=True)
print("top-level statements:", len(tree.body))
for node in ast.walk(tree):
if isinstance(node, ast.For) and isinstance(node.iter, ast.Attribute) and node.iter.attr == "items":
line=node.lineno
starts=[start.lineno for start in [node.body[0], node.orelse[0]] if hasattr(start,'lineno')]
print(f"For at line {line} body starts at line {node.body[0].lineno}, orelse starts at line {node.orelse[0].lineno if node.orelse else None}")
# determine indentation for first statement in orelse if any
stmts=[]
for i,body in enumerate(["for"]):
pass
for child in node.body+node.orelse:
if isinstance(child, ast.Call) and isinstance(child.func, ast.Attribute):
print(f"child call {ast.get_source_segment(open(path), child)!r} at line {child.lineno}")
if isinstance(child, ast.Try):
print(f"TRY at line {child.lineno}")
PY
fiRepository: iam-veeramalla/python-for-devops Length of output: 195 🏁 Script executed: #!/bin/bash
set -euo pipefail
file="./Day-11/screener-integration.py"
echo "--- file size and imports/header ---"
wc -l "$file"
head -n 90 "$file" | awk '{printf "%4d\t%s\n", NR, $0}'
echo "--- search exception/request handling ---"
grep -nE "requests\.post|RequestException|except\s+.*Exception|try:|continue|break|for\s+tag\s+in\s+PAYLOADS" "$file" || true
echo "--- static indentation/source around loop ---"
python3 - <<'PY'
from pathlib import Path
p=Path("Day-11/screener-integration.py")
source=p.read_text().splitlines()
for i,line in enumerate(source[:95],1):
if "for tag" in line or "requests.post" in line or i in range(70,90):
print(f"{i:4}: [{line[:80]}]")
PYRepository: iam-veeramalla/python-for-devops Length of output: 16246 Handle request failures for each payload. The per-payload Proposed fix for tag, payload in PAYLOADS.items():
- response = requests.post(URL, headers=HEADERS, cookies=COOKIES, json=payload, timeout=30)
+ try:
+ response = requests.post(URL, headers=HEADERS, cookies=COOKIES, json=payload, timeout=30)
+ except requests.RequestException as exc:
+ print(f"Unable to request {tag}: {exc}")
+ continue
print(f"\nTag: {tag} | Status code: {response.status_code}")📝 Committable suggestion
Suggested change
🧰 Tools🪛 ast-grep (0.45.0)[warning] 72-72: Request-controlled URL passed to requests; validate against an allowlist to prevent SSRF. (ssrf-requests) 🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| try: | ||||||||||||||||||||||
| content_encoding = response.headers.get("content-encoding", "").lower() | ||||||||||||||||||||||
| decoded_body = response.text or "" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if not decoded_body and brotli is not None and "br" in content_encoding: | ||||||||||||||||||||||
| decoded_body = brotli.decompress(response.content).decode("utf-8", errors="replace") | ||||||||||||||||||||||
| elif not decoded_body: | ||||||||||||||||||||||
| decoded_body = response.content.decode("utf-8", errors="replace") | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| data = json.loads(decoded_body) | ||||||||||||||||||||||
| rows = data.get("data", []) | ||||||||||||||||||||||
| if not rows: | ||||||||||||||||||||||
| print(f"No matching records found for {tag}.") | ||||||||||||||||||||||
| continue | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for item in rows: | ||||||||||||||||||||||
| code = item.get("nsecode", "") | ||||||||||||||||||||||
| name = item.get("name", "") | ||||||||||||||||||||||
| key = (code, name) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if key not in aggregated_rows: | ||||||||||||||||||||||
| aggregated_rows[key] = { | ||||||||||||||||||||||
| "code": code, | ||||||||||||||||||||||
| "name": name, | ||||||||||||||||||||||
| "close": item.get("scan-column-default-close", ""), | ||||||||||||||||||||||
| "change": item.get("scan-column-default-percent-change", ""), | ||||||||||||||||||||||
| "volume": item.get("scan-column-default-volume", ""), | ||||||||||||||||||||||
| "tags": [tag], | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| elif tag not in aggregated_rows[key]["tags"]: | ||||||||||||||||||||||
| aggregated_rows[key]["tags"].append(tag) | ||||||||||||||||||||||
| except (ValueError, json.JSONDecodeError, AttributeError) as exc: | ||||||||||||||||||||||
| print(f"Unable to parse response for {tag}: {exc}") | ||||||||||||||||||||||
| print(decoded_body[:4000] if "decoded_body" in locals() else response.text[:4000]) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| print("\n SCRIPT: MULTI-PAYLOAD SCREENER RESULTS") | ||||||||||||||||||||||
| print("\nFormatted table:") | ||||||||||||||||||||||
| if not aggregated_rows: | ||||||||||||||||||||||
| print("No matching records found.") | ||||||||||||||||||||||
| else: | ||||||||||||||||||||||
| headers = ["CODE", "NAME", "TAGS", "CLOSE", "CHANGE %", "VOLUME"] | ||||||||||||||||||||||
| ranked_rows = sorted( | ||||||||||||||||||||||
| aggregated_rows.values(), | ||||||||||||||||||||||
| key=lambda item: (-len(item["tags"]), item["code"], item["name"]), | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| max_tag_count = max((len(row["tags"]) for row in ranked_rows), default=0) | ||||||||||||||||||||||
| shortlisted_rows = [row for row in ranked_rows if len(row["tags"]) == max_tag_count] | ||||||||||||||||||||||
| selected_rows = shortlisted_rows[:5] | ||||||||||||||||||||||
|
Comment on lines
+121
to
+123
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Select the first five ranked rows. Lines 121-123 discard every row below the highest tag count. If one stock has the most tags, the table prints only that stock even when other ranked matches exist. Select the first five rows from Proposed fix- max_tag_count = max((len(row["tags"]) for row in ranked_rows), default=0)
- shortlisted_rows = [row for row in ranked_rows if len(row["tags"]) == max_tag_count]
- selected_rows = shortlisted_rows[:5]
+ selected_rows = ranked_rows[:5]📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| rows_display = [ | ||||||||||||||||||||||
| [ | ||||||||||||||||||||||
| row["code"], | ||||||||||||||||||||||
| row["name"], | ||||||||||||||||||||||
| ", ".join(row["tags"]), | ||||||||||||||||||||||
| row["close"], | ||||||||||||||||||||||
| row["change"], | ||||||||||||||||||||||
| row["volume"], | ||||||||||||||||||||||
| ] | ||||||||||||||||||||||
| for row in selected_rows | ||||||||||||||||||||||
| ] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| col_widths = [max(len(str(row[i])) for row in [headers] + rows_display) for i in range(len(headers))] | ||||||||||||||||||||||
| print(" | ".join(header.ljust(col_widths[i]) for i, header in enumerate(headers))) | ||||||||||||||||||||||
| print("-+-".join("-" * width for width in col_widths)) | ||||||||||||||||||||||
| for row in rows_display: | ||||||||||||||||||||||
| print(" | ".join(str(value).ljust(col_widths[i]) for i, value in enumerate(row))) | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| student_properties= { | ||
| "name":"abhi", | ||
| "class":"12th" | ||
| } | ||
|
|
||
| students_info=[ | ||
| { | ||
| "name":"nishka", | ||
| "class":"12th" | ||
| }, | ||
| { | ||
| "name":"kiyana", | ||
| "class":"12th" | ||
| }] | ||
|
|
||
| print (student_properties ["name"]) | ||
| print (students_info[0]["name"]) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||||||
| def updatefileProperties (filePath,key,value): | ||||||||||||||||||
| with open(filePath,"r") as serverConf: | ||||||||||||||||||
| lines = serverConf.readlines(); | ||||||||||||||||||
|
|
||||||||||||||||||
| with open(filePath,"w") as serverConf: | ||||||||||||||||||
| for line in lines: | ||||||||||||||||||
| if key in line: | ||||||||||||||||||
| serverConf.write(key+"="+value+"\n") | ||||||||||||||||||
|
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Match the configuration key exactly.
Proposed fix- if key in line:
+ key_part, separator, _ = line.partition("=")
+ if separator and key_part.strip() == key:
serverConf.write(key+"="+value+"\n")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| else: | ||||||||||||||||||
| serverConf.write(line) | ||||||||||||||||||
|
Comment on lines
+5
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== repo files matching fileoperations.py =="
fd -a 'fileoperations\.py$' . || true
echo "== target file contents with line numbers =="
if [ -f Day-12/fileoperations.py ]; then
cat -n Day-12/fileoperations.py
fi
echo "== references to update/create/write config functions =="
rg -n "def |open\\(|write\\(|update|create|conf" Day-12/fileoperations.py . 2>/dev/null | head -200 || true
echo "== relevant imports/usages from nearby tracked files =="
git ls-files Day-12 | xargs -r -n1 sh -c 'echo "--- $0"; sed -n "1,160p" "$0"' 2>/dev/null | head -300Repository: iam-veeramalla/python-for-devops Length of output: 14944 Write the configuration atomically.
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| updatefileProperties("server.conf","MAX_CONNECTIONS","200") | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | sed -n '1,120p'
echo
echo "Day-12 candidates:"
fd -a . Day-12 2>/dev/null | sed 's#^\./##' | sed -n '1,120p'
echo
if [ -f Day-12/fileoperations.py ]; then
echo "Day-12/fileoperations.py outline:"
ast-grep outline Day-12/fileoperations.py || true
echo
echo "Day-12/fileoperations.py contents:"
cat -n Day-12/fileoperations.py
fi
echo
if [ -f Day-12/fileoperations.py ]; then
echo "Read/write usages in Day-12/fileoperations.py:"
python3 - <<'PY'
from pathlib import Path
p=Path('Day-12/fileoperations.py')
text=p.read_text()
for i,line in enumerate(text.splitlines(),1):
if 'updatefileProperties' in line or 'open(' in line or 'readlines' in line or 'readline' in line or 'write' in line or 'read(' in line:
print(f'{i}: {line}')
PY
fi
echo
echo "server.conf file:"
if [ -f Day-12/server.conf ]; then
cat -n Day-12/server.conf
else
echo "Day-12/server.conf not found"
fi
echo
echo "Python path resolution probe:"
python3 - <<'PY'
from pathlib import Path
for d in ["repo_root", "Day-12", "/tmp"]:
print(d, "->", Path(d).resolve(), "Day-12/server.conf exists from cwd?", (Path(d).resolve()/"Day-12"/"server.conf").exists())
print(d, "->", Path("server.conf").resolve(), "server.conf exists from cwd?", Path("server.conf").resolve().exists())
PYRepository: iam-veeramalla/python-for-devops Length of output: 4741 Resolve
Proposed fix+from pathlib import Path
+
-updatefileProperties("server.conf","MAX_CONNECTIONS","200")
+updatefileProperties(
+ Path(__file__).resolve().with_name("server.conf"),
+ "MAX_CONNECTIONS",
+ "200",
+)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: iam-veeramalla/python-for-devops
Length of output: 1524
🏁 Script executed:
Repository: iam-veeramalla/python-for-devops
Length of output: 16873
🌐 Web query:
Python requests library content-encoding support gzip deflate brotli zstandard💡 Result:
The Python Requests library provides automated decoding for several Content-Encoding types, delegating the underlying work to the urllib3 library [1][2]. Gzip and Deflate: Requests supports these transfer-encodings natively and decodes them automatically [2]. Brotli: Requests supports Brotli encoding automatically if a compatible Brotli library is installed in your environment [2]. Specifically, if either the 'brotli' or 'brotlicffi' package is available, Requests will include 'br' in the Accept-Encoding header and transparently handle the decoding of responses [1][3]. Zstandard (zstd): Requests does not have native support for Zstandard (zstd) decompression [4]. If the 'zstandard' library is installed, some third-party packages or system configurations may automatically include 'zstd' in the Accept-Encoding header, which can cause issues if your environment expects standard Requests behavior [4]. In such cases, users may need to manually uninstall the 'zstandard' package or explicitly override the Accept-Encoding header in their requests to exclude 'zstd' [4]. In summary, for gzip, deflate, and brotli, decompression is handled transparently, provided the necessary dependencies are present [2]. For other encodings like zstd, you may need to manage the headers or decompression manually [4].
Citations:
Do not advertise unsupported response encodings.
HEADERS["accept-encoding"]advertiseszstd, butDay-11/screener-integration.pyonly conditionally supports Brotli and has no Zstandard decoder. Advertised encodings should be limited to codecs the intended runtime can decode; keepgzip, deflateif that is the supported baseline.Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 Betterleaks (1.7.0)
[high] 28-28: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents