Files
namecheap-api/update_prices.py
kaffa 896699535d Initial commit: Namecheap API library with REST/MCP servers
Features:
- Domain management (check, register, renew, contacts)
- DNS management (nameservers, records)
- Glue records (child nameserver) support
- TLD price tracking with KRW conversion
- FastAPI REST server with OpenAI schema
- MCP server for Claude integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 10:21:46 +09:00

134 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Update TLD prices from Namecheap API with current exchange rate
"""
import os
import math
import requests
import xml.etree.ElementTree as ET
from datetime import datetime
from dotenv import load_dotenv
from db import get_connection, init_db
load_dotenv()
NS = {"nc": "http://api.namecheap.com/xml.response"}
def get_exchange_rate() -> float:
"""Fetch current USD to KRW exchange rate"""
resp = requests.get(
"https://api.exchangerate-api.com/v4/latest/USD",
timeout=30
)
resp.raise_for_status()
return resp.json()["rates"]["KRW"]
def get_namecheap_prices() -> dict[str, float]:
"""Fetch domain prices from Namecheap API"""
params = {
"ApiUser": os.getenv("NAMECHEAP_API_USER"),
"ApiKey": os.getenv("NAMECHEAP_API_KEY"),
"UserName": os.getenv("NAMECHEAP_USERNAME"),
"ClientIp": os.getenv("NAMECHEAP_CLIENT_IP"),
"Command": "namecheap.users.getPricing",
"ProductType": "DOMAIN",
"ProductCategory": "REGISTER",
}
resp = requests.get(
"https://api.namecheap.com/xml.response",
params=params,
timeout=120
)
resp.raise_for_status()
root = ET.fromstring(resp.text)
prices = {}
for product in root.findall(".//nc:Product", NS):
tld = product.attrib.get("Name")
for price in product.findall(".//nc:Price", NS):
if price.attrib.get("Duration") == "1":
prices[tld] = float(price.attrib.get("Price", 0))
break
return prices
VAT = 1.10 # 부가세 10%
MARGIN = 1.03 # 마진 3%
def to_krw_1000(usd: float, rate: float) -> int:
"""Convert USD to KRW with VAT + margin, rounded up to nearest 1000"""
krw = usd * rate * VAT * MARGIN
return math.ceil(krw / 1000) * 1000
def update_database(prices: dict[str, float], rate: float):
"""Update database with new prices"""
conn = get_connection()
now = datetime.now().isoformat()
# Update exchange rate
conn.execute(
"""
INSERT OR REPLACE INTO exchange_rates (currency, rate, updated_at)
VALUES (?, ?, ?)
""",
("KRW", rate, now)
)
# Update TLD prices
for tld, usd in prices.items():
krw = to_krw_1000(usd, rate)
conn.execute(
"""
INSERT OR REPLACE INTO tld_prices (tld, usd, krw, updated_at)
VALUES (?, ?, ?, ?)
""",
(tld, usd, krw, now)
)
conn.commit()
conn.close()
def main():
print(f"[{datetime.now()}] Starting price update...")
# Initialize DB if needed
init_db()
# Get exchange rate
print("Fetching exchange rate...")
rate = get_exchange_rate()
print(f"USD/KRW: {rate:.2f}")
# Get prices from Namecheap
print("Fetching Namecheap prices...")
prices = get_namecheap_prices()
print(f"Got {len(prices)} TLD prices")
# Update database
print("Updating database...")
update_database(prices, rate)
print("Done!")
# Show some popular TLDs
popular = ["com", "net", "org", "io", "dev", "app", "me", "xyz", "co", "in"]
print("\nPopular TLDs:")
for tld in popular:
if tld in prices:
krw = to_krw_1000(prices[tld], rate)
print(f" .{tld:6} ${prices[tld]:6.2f}{krw:,}")
if __name__ == "__main__":
main()