fix: remove stale _decimal_str ref, add context manager to HTTP clients
- UpstreamClient & Sub2ApiWebsiteClient: add __enter__/__exit__ - Convert all call sites to `with Client(...) as c:` pattern - Remove unused `upstream_name`/`upstream_base_url` locals in scheduler - Fix stale _decimal_str→decimal_string in _rate_from_group
This commit is contained in:
@@ -146,13 +146,13 @@ def test_upstream(uid: int, db: Session = Depends(get_db), _=Depends(get_current
|
|||||||
if not u:
|
if not u:
|
||||||
raise HTTPException(404, "upstream not found")
|
raise HTTPException(404, "upstream not found")
|
||||||
auth_config = json.loads(u.auth_config_json or "{}")
|
auth_config = json.loads(u.auth_config_json or "{}")
|
||||||
client = UpstreamClient(
|
with UpstreamClient(
|
||||||
base_url=u.base_url,
|
base_url=u.base_url,
|
||||||
api_prefix=u.api_prefix,
|
api_prefix=u.api_prefix,
|
||||||
auth_type=u.auth_type,
|
auth_type=u.auth_type,
|
||||||
auth_config=auth_config,
|
auth_config=auth_config,
|
||||||
timeout=float(u.timeout_seconds),
|
timeout=float(u.timeout_seconds),
|
||||||
)
|
) as client:
|
||||||
try:
|
try:
|
||||||
client.login()
|
client.login()
|
||||||
groups = client.get_available_groups(u.groups_endpoint)
|
groups = client.get_available_groups(u.groups_endpoint)
|
||||||
@@ -177,13 +177,13 @@ def check_now(uid: int, db: Session = Depends(get_db), _=Depends(get_current_use
|
|||||||
if not u:
|
if not u:
|
||||||
raise HTTPException(404, "upstream not found")
|
raise HTTPException(404, "upstream not found")
|
||||||
auth_config = json.loads(u.auth_config_json or "{}")
|
auth_config = json.loads(u.auth_config_json or "{}")
|
||||||
client = UpstreamClient(
|
with UpstreamClient(
|
||||||
base_url=u.base_url,
|
base_url=u.base_url,
|
||||||
api_prefix=u.api_prefix,
|
api_prefix=u.api_prefix,
|
||||||
auth_type=u.auth_type,
|
auth_type=u.auth_type,
|
||||||
auth_config=auth_config,
|
auth_config=auth_config,
|
||||||
timeout=float(u.timeout_seconds),
|
timeout=float(u.timeout_seconds),
|
||||||
)
|
) as client:
|
||||||
try:
|
try:
|
||||||
client.login()
|
client.login()
|
||||||
groups = client.get_available_groups(u.groups_endpoint)
|
groups = client.get_available_groups(u.groups_endpoint)
|
||||||
|
|||||||
@@ -188,7 +188,8 @@ def test_website(wid: int, db: Session = Depends(get_db), _=Depends(get_current_
|
|||||||
if not row:
|
if not row:
|
||||||
raise HTTPException(404, "website not found")
|
raise HTTPException(404, "website not found")
|
||||||
try:
|
try:
|
||||||
groups = _client(row).get_groups(row.groups_endpoint)
|
with _client(row) as c:
|
||||||
|
groups = c.get_groups(row.groups_endpoint)
|
||||||
row.last_status = "healthy"
|
row.last_status = "healthy"
|
||||||
row.last_error = None
|
row.last_error = None
|
||||||
row.last_checked_at = datetime.now(timezone.utc)
|
row.last_checked_at = datetime.now(timezone.utc)
|
||||||
@@ -208,7 +209,8 @@ def list_website_groups(wid: int, db: Session = Depends(get_db), _=Depends(get_c
|
|||||||
if not row:
|
if not row:
|
||||||
raise HTTPException(404, "website not found")
|
raise HTTPException(404, "website not found")
|
||||||
try:
|
try:
|
||||||
return _client(row).get_groups(row.groups_endpoint)
|
with _client(row) as c:
|
||||||
|
return c.get_groups(row.groups_endpoint)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise HTTPException(502, str(exc))
|
raise HTTPException(502, str(exc))
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ def _check_upstream(upstream_id: int) -> None:
|
|||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
# ── Phase 1: upstream check + DB write ──────────────────────────
|
# ── Phase 1: upstream check + DB write ──────────────────────────
|
||||||
db: Session = SessionLocal()
|
db: Session = SessionLocal()
|
||||||
client = None
|
|
||||||
try:
|
try:
|
||||||
upstream = db.query(Upstream).filter(Upstream.id == upstream_id).first()
|
upstream = db.query(Upstream).filter(Upstream.id == upstream_id).first()
|
||||||
if not upstream or not upstream.enabled:
|
if not upstream or not upstream.enabled:
|
||||||
@@ -45,18 +44,17 @@ def _check_upstream(upstream_id: int) -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
auth_config = json.loads(upstream.auth_config_json or "{}")
|
auth_config = json.loads(upstream.auth_config_json or "{}")
|
||||||
client = UpstreamClient(
|
was_unhealthy = upstream.last_status == "unhealthy"
|
||||||
|
snapshot = None
|
||||||
|
changes = None
|
||||||
|
|
||||||
|
with UpstreamClient(
|
||||||
base_url=upstream.base_url,
|
base_url=upstream.base_url,
|
||||||
api_prefix=upstream.api_prefix,
|
api_prefix=upstream.api_prefix,
|
||||||
auth_type=upstream.auth_type,
|
auth_type=upstream.auth_type,
|
||||||
auth_config=auth_config,
|
auth_config=auth_config,
|
||||||
timeout=float(upstream.timeout_seconds),
|
timeout=float(upstream.timeout_seconds),
|
||||||
)
|
) as client:
|
||||||
|
|
||||||
was_unhealthy = upstream.last_status == "unhealthy"
|
|
||||||
snapshot = None
|
|
||||||
changes = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.login()
|
client.login()
|
||||||
groups = client.get_available_groups(upstream.groups_endpoint)
|
groups = client.get_available_groups(upstream.groups_endpoint)
|
||||||
@@ -84,7 +82,7 @@ def _check_upstream(upstream_id: int) -> None:
|
|||||||
"upstream_unhealthy", str(exc))
|
"upstream_unhealthy", str(exc))
|
||||||
return
|
return
|
||||||
|
|
||||||
# success path
|
# success path (client auto-closed by `with`)
|
||||||
prev_snapshot_row = (
|
prev_snapshot_row = (
|
||||||
db.query(UpstreamRateSnapshot)
|
db.query(UpstreamRateSnapshot)
|
||||||
.filter(UpstreamRateSnapshot.upstream_id == upstream_id)
|
.filter(UpstreamRateSnapshot.upstream_id == upstream_id)
|
||||||
@@ -116,7 +114,6 @@ def _check_upstream(upstream_id: int) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
client.close()
|
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
# ── Phase 2: notifications (independent sessions) ──────────────
|
# ── Phase 2: notifications (independent sessions) ──────────────
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def _rate_from_group(group: dict[str, Any]) -> str:
|
|||||||
"effective_rate_multiplier", "effectiveRateMultiplier",
|
"effective_rate_multiplier", "effectiveRateMultiplier",
|
||||||
"rate_multiplier", "rateMultiplier",
|
"rate_multiplier", "rateMultiplier",
|
||||||
):
|
):
|
||||||
r = _decimal_str(group.get(key))
|
r = decimal_string(group.get(key))
|
||||||
if r:
|
if r:
|
||||||
return r
|
return r
|
||||||
return ""
|
return ""
|
||||||
@@ -214,6 +214,12 @@ class UpstreamClient:
|
|||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
self._client.close()
|
self._client.close()
|
||||||
|
|
||||||
|
def __enter__(self) -> UpstreamClient:
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args: Any) -> None:
|
||||||
|
self.close()
|
||||||
|
|
||||||
def _url(self, path: str) -> str:
|
def _url(self, path: str) -> str:
|
||||||
prefix = f"/{self.api_prefix}" if self.api_prefix else ""
|
prefix = f"/{self.api_prefix}" if self.api_prefix else ""
|
||||||
return f"{self.base_url}{prefix}/{path.lstrip('/')}"
|
return f"{self.base_url}{prefix}/{path.lstrip('/')}"
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ class Sub2ApiWebsiteClient:
|
|||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
self._client.close()
|
self._client.close()
|
||||||
|
|
||||||
|
def __enter__(self) -> Sub2ApiWebsiteClient:
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args: Any) -> None:
|
||||||
|
self.close()
|
||||||
|
|
||||||
def _url(self, path: str) -> str:
|
def _url(self, path: str) -> str:
|
||||||
prefix = f"/{self.api_prefix}" if self.api_prefix else ""
|
prefix = f"/{self.api_prefix}" if self.api_prefix else ""
|
||||||
return f"{self.base_url}{prefix}/{path.lstrip('/')}"
|
return f"{self.base_url}{prefix}/{path.lstrip('/')}"
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ def sync_binding(db: Session, binding: WebsiteGroupBinding, write: bool = True)
|
|||||||
old_rate = None
|
old_rate = None
|
||||||
if write and website.enabled and website.auto_sync_enabled and binding.enabled:
|
if write and website.enabled and website.auto_sync_enabled and binding.enabled:
|
||||||
try:
|
try:
|
||||||
client = _client_for(website)
|
with _client_for(website) as client:
|
||||||
groups = client.get_groups(website.groups_endpoint)
|
groups = client.get_groups(website.groups_endpoint)
|
||||||
target = next((item for item in groups if item.get("id") == binding.target_group_id), None)
|
target = next((item for item in groups if item.get("id") == binding.target_group_id), None)
|
||||||
old_rate = target.get("rate_multiplier") if target else None
|
old_rate = target.get("rate_multiplier") if target else None
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ from app.services.upstream_client import UpstreamClient
|
|||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
client = UpstreamClient(
|
with UpstreamClient(
|
||||||
base_url="http://170.106.100.210:55555",
|
base_url="http://170.106.100.210:55555",
|
||||||
api_prefix="",
|
api_prefix="",
|
||||||
auth_type="bearer",
|
auth_type="bearer",
|
||||||
auth_config={"token": ""}, # We don't have token, but /api/group/ in some new-api may be open, or fail with 401
|
auth_config={"token": ""}, # We don't have token, but /api/group/ in some new-api may be open, or fail with 401
|
||||||
timeout=10.0,
|
timeout=10.0,
|
||||||
)
|
) as client:
|
||||||
try:
|
try:
|
||||||
groups = client.get_available_groups("/api/group/")
|
groups = client.get_available_groups("/api/group/")
|
||||||
print("Groups:", groups)
|
print("Groups:", groups)
|
||||||
|
|||||||
Reference in New Issue
Block a user