refactor(paths): replace 26 modules hardcoded ~/.pry/ with PRY_DATA_DIR
Each module did:
X_DIR = Path(os.path.expanduser("~/.pry/x"))
After:
from paths import PRY_DATA_DIR
X_DIR = PRY_DATA_DIR / "x"
The module-level Path construction is preserved, so the rest of the
code is unchanged. PRY_DATA_DIR is read once at import (overridable via
the env var of the same name).
Verified:
- 407 tests collect (was 5 collection errors from a misplaced import)
- 83 sampled tests pass (intelligence, proxy_manager, x402, agency,
gdpr, referrals, marketplace, api)
- 0 remaining hardcoded ~/.pry references in .py files
Follow-up: paths.py adds subdir(name) helper for new code that wants
auto-mkdir; existing modules still call .mkdir(exist_ok=True) themselves
to preserve the eager-init behavior they had before.
This commit is contained in:
parent
c2c33c4d9f
commit
dd63022530
26 changed files with 53 additions and 28 deletions
|
|
@ -13,9 +13,10 @@ from datetime import UTC, datetime
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from paths import PRY_DATA_DIR
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ACCOUNTS_DIR = Path(os.path.expanduser("~/.pry/accounts"))
|
||||
ACCOUNTS_DIR = PRY_DATA_DIR / "accounts"
|
||||
ACCOUNTS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Pry — Actor Marketplace (Apify-style).
|
||||
Pre-built scrapers that can be subscribed to and run on schedule.
|
||||
Users can publish their own actors. We earn from usage."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -19,7 +20,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ACTOR_DIR = Path(os.path.expanduser("~/.pry/actors"))
|
||||
ACTOR_DIR = PRY_DATA_DIR / "actors"
|
||||
ACTOR_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — White-Label Agency Dashboard.
|
||||
Multi-tenant reseller platform: custom branding, client management, sub-accounts."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -17,7 +18,7 @@ from typing import Any, cast
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
AGENCY_DIR = Path(os.path.expanduser("~/.pry/agency"))
|
||||
AGENCY_DIR = PRY_DATA_DIR / "agency"
|
||||
AGENCY_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Enterprise SSO / Auth Connector System.
|
||||
Credential vault, session persistence, SSO flow automation, CAPTCHA integration."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: BSL-1.1
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -20,7 +21,7 @@ from typing import Any, Literal, cast
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
VAULT_DIR = Path(os.path.expanduser("~/.pry/vault"))
|
||||
VAULT_DIR = PRY_DATA_DIR / "vault"
|
||||
VAULT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# ── Credential Vault (encrypted at rest) ──
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Commerce Platform Sync Engine.
|
||||
Unified interface for WooCommerce, Shopify, and generic API sync."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -16,7 +17,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
# ── Record sync operation ──
|
||||
|
||||
COMMERCE_DIR = Path(os.path.expanduser("~/.pry/commerce"))
|
||||
COMMERCE_DIR = PRY_DATA_DIR / "commerce"
|
||||
COMMERCE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Cost Analytics Engine.
|
||||
Tracks usage costs, cache hit rates, projected burn, and smart scheduling."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -17,7 +18,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
COSTING_DIR = Path(os.path.expanduser("~/.pry/costing"))
|
||||
COSTING_DIR = PRY_DATA_DIR / "costing"
|
||||
COSTING_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Cost per operation (in USD, configurable)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Adaptive Freshness Scheduling.
|
||||
Conditional scraping, content fingerprinting, staleness dashboard, adaptive frequency."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -18,7 +19,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
FRESHNESS_DIR = Path(os.path.expanduser("~/.pry/freshness"))
|
||||
FRESHNESS_DIR = PRY_DATA_DIR / "freshness"
|
||||
FRESHNESS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
3
gdpr.py
3
gdpr.py
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — GDPR Compliance Portal.
|
||||
Data deletion API, consent management, retention policies, audit log."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -19,7 +20,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GDPR_DIR = Path(os.path.expanduser("~/.pry/gdpr"))
|
||||
GDPR_DIR = PRY_DATA_DIR / "gdpr"
|
||||
GDPR_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
CONSENT_DIR = GDPR_DIR / "consent"
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ from datetime import UTC, datetime
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from paths import PRY_DATA_DIR
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GDPR_DIR = Path(os.path.expanduser("~/.pry/gdpr_real"))
|
||||
GDPR_DIR = PRY_DATA_DIR / "gdpr_real"
|
||||
GDPR_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
DATA_RESIDENCES = [
|
||||
|
|
@ -61,7 +62,7 @@ class GDPRService:
|
|||
"records": {},
|
||||
"total_records": 0,
|
||||
}
|
||||
pry_dir = Path(os.path.expanduser("~/.pry"))
|
||||
pry_dir = PRY_DATA_DIR
|
||||
subject_lower = subject_id.lower()
|
||||
for subdir in DATA_RESIDENCES:
|
||||
subdir_path = pry_dir / subdir
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Competitive Intelligence Engine.
|
||||
Historical snapshots, anomaly detection, natural-language alerts, weekly reports."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -18,7 +19,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
INTEL_DIR = Path(os.path.expanduser("~/.pry/intel"))
|
||||
INTEL_DIR = PRY_DATA_DIR / "intel"
|
||||
INTEL_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@ from typing import Any
|
|||
|
||||
from llm_providers.base import LLMProvider, LLMResponse, ReferralConfig
|
||||
|
||||
from paths import PRY_DATA_DIR
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
USAGE_DIR = Path(os.path.expanduser("~/.pry/llm_usage"))
|
||||
USAGE_DIR = PRY_DATA_DIR / "llm_usage"
|
||||
USAGE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — scheduled monitors with AI change detection.
|
||||
Cron-based monitors that diff content and judge meaningful changes."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -20,7 +21,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MONITORS_DIR = Path(os.path.expanduser("~/.pry/monitors"))
|
||||
MONITORS_DIR = PRY_DATA_DIR / "monitors"
|
||||
MONITORS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ JSON-defined workflow engine. Users define pipelines as structured steps,
|
|||
the engine executes them sequentially with branching and error handling.
|
||||
|
||||
A UI can render these steps as drag-and-drop blocks."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -20,7 +21,7 @@ from typing import Any, cast
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PIPELINE_DIR = Path(os.path.expanduser("~/.pry/pipelines"))
|
||||
PIPELINE_DIR = PRY_DATA_DIR / "pipelines"
|
||||
PIPELINE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# ── Step Types Registry ──
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Pry — Proxy Manager with affiliate-signup flow.
|
||||
Tries free proxies first (Tor, public rotating). When premium proxy is needed,
|
||||
prompts user to sign up via affiliate links. Pre-wired to 5+ providers."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -24,7 +25,7 @@ try:
|
|||
except ImportError: # proxy_referrals module not always present in slim installs
|
||||
_PROXY_REFERRALS = {}
|
||||
|
||||
PROXY_DIR = Path(os.path.expanduser("~/.pry/proxies"))
|
||||
PROXY_DIR = PRY_DATA_DIR / "proxies"
|
||||
PROXY_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Free proxy sources (no signup required)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Data Quality SLA Dashboard.
|
||||
Per-extraction quality metrics, anomaly detection, freshness tracking."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -20,7 +21,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
QUALITY_DIR = Path(os.path.expanduser("~/.pry/quality"))
|
||||
QUALITY_DIR = PRY_DATA_DIR / "quality"
|
||||
QUALITY_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# ── Quality Metrics ──
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Pry — Referral / Affiliate revenue system.
|
||||
Tracks clicks, conversions, and revenue across 60+ providers.
|
||||
Supports x402 (HTTP 402) pay-per-scrape protocol for monetization."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -18,7 +19,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REFERRAL_DIR = Path(os.path.expanduser("~/.pry/referrals"))
|
||||
REFERRAL_DIR = PRY_DATA_DIR / "referrals"
|
||||
REFERRAL_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Provider catalog with referral program details
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Automated White-Label Report Generator.
|
||||
Generate branded PDF/HTML reports from scraped data for client delivery."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -16,7 +17,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REPORTS_DIR = Path(os.path.expanduser("~/.pry/reports"))
|
||||
REPORTS_DIR = PRY_DATA_DIR / "reports"
|
||||
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ from html.parser import HTMLParser
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from paths import PRY_DATA_DIR
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REPORTS_DIR = Path(os.path.expanduser("~/.pry/reports_real"))
|
||||
REPORTS_DIR = PRY_DATA_DIR / "reports_real"
|
||||
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Human-in-the-Loop Validation Workflow.
|
||||
Routes low-confidence extractions to human review before delivery."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -17,7 +18,7 @@ from typing import Any, cast
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REVIEW_DIR = Path(os.path.expanduser("~/.pry/reviews"))
|
||||
REVIEW_DIR = PRY_DATA_DIR / "reviews"
|
||||
REVIEW_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Status enum for review items
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — SEO Content Change Monitor.
|
||||
Track competitor meta tags, titles, descriptions, headings, content changes."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -19,7 +20,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SEO_DIR = Path(os.path.expanduser("~/.pry/seo"))
|
||||
SEO_DIR = PRY_DATA_DIR / "seo"
|
||||
SEO_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — persistent browser session management.
|
||||
Saves and restores Playwright browser contexts to disk."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -17,7 +18,7 @@ from typing import Any, cast
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SESSIONS_DIR = Path(os.path.expanduser("~/.pry/sessions"))
|
||||
SESSIONS_DIR = PRY_DATA_DIR / "sessions"
|
||||
SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Page Structure Monitor.
|
||||
Track CSS selector validity over time. Alert before scrapers break."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -22,7 +23,7 @@ from client import get_client
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
STRUCTURE_DIR = Path(os.path.expanduser("~/.pry/structure"))
|
||||
STRUCTURE_DIR = PRY_DATA_DIR / "structure"
|
||||
STRUCTURE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
3
tasks.py
3
tasks.py
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Background job system using asyncio (built-in) or Celery if available.
|
||||
Long-running jobs like crawls, monitors, and bulk imports should not block request threads."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -27,7 +28,7 @@ try:
|
|||
except ImportError:
|
||||
_has_celery = False
|
||||
|
||||
JOBS_DIR = Path(os.path.expanduser("~/.pry/jobs"))
|
||||
JOBS_DIR = PRY_DATA_DIR / "jobs"
|
||||
JOBS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — AI Training Data Pipeline.
|
||||
Per-record provenance, license classifier, clean room export, compliance reports."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -21,7 +22,7 @@ from typing import Any, Literal
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TRAINING_DIR = Path(os.path.expanduser("~/.pry/training"))
|
||||
TRAINING_DIR = PRY_DATA_DIR / "training"
|
||||
TRAINING_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# ── License Classification ──
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Pry — Webhook Delivery Service.
|
||||
Reliable webhook delivery with retries, signing (HMAC), and dead letter queue."""
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
|
|
@ -20,7 +21,7 @@ from typing import Any
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
WEBHOOK_DIR = Path(os.path.expanduser("~/.pry/webhooks"))
|
||||
WEBHOOK_DIR = PRY_DATA_DIR / "webhooks"
|
||||
WEBHOOK_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
|
|
|
|||
4
x402.py
4
x402.py
|
|
@ -12,7 +12,6 @@ Standards compliance:
|
|||
- Multiple facilitators: coinbase, payai, cloudflare, eip-7702
|
||||
- Smart facilitator router with auto-fallback
|
||||
"""
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2026 Rug Munch Media LLC
|
||||
#
|
||||
|
|
@ -20,6 +19,7 @@ Standards compliance:
|
|||
# Licensed under MIT. See LICENSE.
|
||||
|
||||
from __future__ import annotations
|
||||
from paths import PRY_DATA_DIR
|
||||
|
||||
import base64
|
||||
import json
|
||||
|
|
@ -37,7 +37,7 @@ import httpx
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
X402_DIR = Path(os.path.expanduser("~/.pry/x402"))
|
||||
X402_DIR = PRY_DATA_DIR / "x402"
|
||||
X402_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# x402 pricing per operation (USDC atomic units, 6 decimals)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue