v6.7.0: Python API桥接 — Web应用前后端统一使用v6.6.0精算引擎
## 新增 - jyotish_api_server.py: FastAPI式HTTP服务器(10个端点) - POST /api/chart — 完整星盘(35种Dasha+Yoga+行星) - POST /api/remedies — 5类补救建议 - POST /api/kp — KP分析 - POST /api/prashna — 卜卦 - POST /api/synastry — 合盘 - POST /api/sade_sati/pancha_mahapurusha/career/relationship - GET /api/health + /api/cities - api-bridge.js: 前端API桥接模块(自动检测+降级) - main.js: 优先使用Python API,不可用时回退JS引擎 ## 关键修复 - 前后端现在使用同一套v6.6.0精算引擎(35种Dasha, 107+ Yoga) - Web应用不再受限于v0.1 JS引擎的有限计算能力 - 启动: python3 scripts/jyotish_api_server.py --port 5200
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* API Bridge v1.0
|
||||
* 连接前端到 Python v6.6.0 精算引擎
|
||||
*
|
||||
* 用法: 在 index.html 中加载此脚本后,自动检测并优先使用 Python API
|
||||
*/
|
||||
const API_BASE = 'http://localhost:5200';
|
||||
|
||||
async function apiFetch(endpoint, body = {}) {
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE}${endpoint}`, {
|
||||
method: body && Object.keys(body).length > 0 ? 'POST' : 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: body && Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
return await resp.json();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkApiAvailable() {
|
||||
const r = await apiFetch('/api/health');
|
||||
return r && r.status === 'ok';
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Python API 计算完整星盘
|
||||
* 替代原有的 jyotish-engine.js 计算
|
||||
*/
|
||||
async function apiComputeFullChart(birthData) {
|
||||
const result = await apiFetch('/api/chart', birthData);
|
||||
if (!result || !result.success) {
|
||||
throw new Error(result?.error || 'API computation failed');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取补救建议
|
||||
*/
|
||||
async function apiGetRemedies(chartData) {
|
||||
const shadbala = {};
|
||||
if (chartData.planets) {
|
||||
for (const [p, d] of Object.entries(chartData.planets)) {
|
||||
shadbala[p] = { total_rupas: 3.0 }; // 默认值
|
||||
}
|
||||
}
|
||||
return await apiFetch('/api/remedies', {
|
||||
shadbala,
|
||||
doshas: [],
|
||||
dasha_lord: chartData.dasha?.current_md || '',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取KP分析
|
||||
*/
|
||||
async function apiGetKP(chartData) {
|
||||
return await apiFetch('/api/kp', {
|
||||
planets: chartData.planets || {},
|
||||
asc_sign_idx: chartData.ascendant?.sign_idx || 0,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合盘分析
|
||||
*/
|
||||
async function apiGetSynastry(maleMoonDeg, femaleMoonDeg) {
|
||||
return await apiFetch('/api/synastry', {
|
||||
male_moon: maleMoonDeg,
|
||||
female_moon: femaleMoonDeg,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Sade Sati分析
|
||||
*/
|
||||
async function apiGetSadeSati(chartData) {
|
||||
const moon = chartData.planets?.Moon;
|
||||
const sun = chartData.planets?.Sun;
|
||||
return await apiFetch('/api/sade_sati', {
|
||||
moon_degree: moon?.lon || 0,
|
||||
asc_degree: chartData.ascendant?.degree || 0,
|
||||
saturn_degree: chartData.planets?.Saturn?.lon || 0,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Pancha Mahapurusha分析
|
||||
*/
|
||||
async function apiGetPMC(chartData) {
|
||||
return await apiFetch('/api/pancha_mahapurusha', {
|
||||
planets: chartData.planets || {},
|
||||
sun_degree: chartData.planets?.Sun?.lon || 0,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取事业分析
|
||||
*/
|
||||
async function apiGetCareer(chartData) {
|
||||
return await apiFetch('/api/career', {
|
||||
planets: chartData.planets || {},
|
||||
asc_sign: chartData.ascendant?.sign || 'Aries',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取感情分析
|
||||
*/
|
||||
async function apiGetRelationship(chartData) {
|
||||
return await apiFetch('/api/relationship', {
|
||||
planets: chartData.planets || {},
|
||||
asc_sign: chartData.ascendant?.sign || 'Aries',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Prashna卜卦分析
|
||||
*/
|
||||
async function apiGetPrashna(chartData, question) {
|
||||
return await apiFetch('/api/prashna', {
|
||||
planets: chartData.planets || {},
|
||||
question: question || 'general',
|
||||
});
|
||||
}
|
||||
|
||||
// 导出
|
||||
window.JyotishAPI = {
|
||||
checkAvailable: checkApiAvailable,
|
||||
computeChart: apiComputeFullChart,
|
||||
getRemedies: apiGetRemedies,
|
||||
getKP: apiGetKP,
|
||||
getSynastry: apiGetSynastry,
|
||||
getSadeSati: apiGetSadeSati,
|
||||
getPMC: apiGetPMC,
|
||||
getCareer: apiGetCareer,
|
||||
getRelationship: apiGetRelationship,
|
||||
getPrashna: apiGetPrashna,
|
||||
baseUrl: API_BASE,
|
||||
};
|
||||
@@ -426,6 +426,7 @@
|
||||
</div>
|
||||
|
||||
<script type="module" src="/swisseph-wasm/src/swisseph.js"></script>
|
||||
<script src="/api-bridge.js"></script>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+22
-2
@@ -216,8 +216,28 @@ function setupForm() {
|
||||
const [hour, minute] = timeVal.split(':').map(Number);
|
||||
btnText.classList.add('hidden'); btnLoading.classList.remove('hidden'); btn.disabled = true;
|
||||
try {
|
||||
await initEngine();
|
||||
chartData = await computeChart({ year, month, day, hour, minute, lat, lon, tz });
|
||||
// ✨ v6.6.0: 优先尝试 Python API 精算引擎
|
||||
let apiResult = null;
|
||||
if (window.JyotishAPI) {
|
||||
const apiAvailable = await window.JyotishAPI.checkAvailable();
|
||||
if (apiAvailable) {
|
||||
try {
|
||||
apiResult = await window.JyotishAPI.computeChart({ year, month, day, hour, minute, lat, lon, tz });
|
||||
if (apiResult && apiResult.success) {
|
||||
chartData = apiResult;
|
||||
console.log('[Jyotish] ✅ Using Python API v6.6.0');
|
||||
}
|
||||
} catch (apiErr) {
|
||||
console.warn('[Jyotish] API unavailable, falling back to JS engine:', apiErr.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 回退到 JS 引擎
|
||||
if (!chartData) {
|
||||
await initEngine();
|
||||
chartData = await computeChart({ year, month, day, hour, minute, lat, lon, tz });
|
||||
console.log('[Jyotish] ⚠️ Fallback to JS engine');
|
||||
}
|
||||
// 保存出生数据供生时校正使用
|
||||
window.__jyotishBirth = { year, month, day, hour, minute, lat, lon, tz };
|
||||
renderAll();
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
印度占星 API 服务器 v1.0
|
||||
为 jyotish-app 前端提供 v6.6.0 引擎的精算能力
|
||||
|
||||
启动: python3 scripts/jyotish_api_server.py --port 5200
|
||||
"""
|
||||
|
||||
import json, sys, os, math
|
||||
from datetime import datetime, timedelta
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
SCRIPTS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, SCRIPTS_DIR)
|
||||
|
||||
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
|
||||
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
|
||||
|
||||
# 城市数据库(简化版)
|
||||
CITY_DB = {
|
||||
'北京': (39.9, 116.4, 8), '上海': (31.2, 121.5, 8), '广州': (23.1, 113.3, 8),
|
||||
'深圳': (22.5, 114.1, 8), '成都': (30.6, 104.1, 8), '重庆': (29.6, 106.5, 8),
|
||||
'杭州': (30.3, 120.2, 8), '南京': (32.1, 118.8, 8), '武汉': (30.6, 114.3, 8),
|
||||
'西安': (34.3, 108.9, 8), '郑州': (34.8, 113.7, 8), '长沙': (28.2, 113.0, 8),
|
||||
'天津': (39.1, 117.2, 8), '香港': (22.3, 114.2, 8), '台北': (25.0, 121.5, 8),
|
||||
'New York': (40.7, -74.0, -5), 'London': (51.5, -0.1, 0),
|
||||
'Tokyo': (35.7, 139.7, 9), 'Sydney': (-33.9, 151.2, 10),
|
||||
'Delhi': (28.6, 77.2, 5.5), 'Mumbai': (19.1, 72.9, 5.5),
|
||||
'Paris': (48.9, 2.3, 1), 'Berlin': (52.5, 13.4, 1),
|
||||
'Los Angeles': (34.1, -118.2, -8), 'Chicago': (41.9, -87.6, -6),
|
||||
'San Francisco': (37.8, -122.4, -8), 'Seattle': (47.6, -122.3, -8),
|
||||
'Boston': (42.4, -71.1, -5), 'Toronto': (43.7, -79.4, -5),
|
||||
'Singapore': (1.3, 103.8, 8), 'Dubai': (25.2, 55.3, 4),
|
||||
}
|
||||
|
||||
|
||||
class JyotishAPIHandler(BaseHTTPRequestHandler):
|
||||
def _json(self, data, status=200):
|
||||
self.send_response(status)
|
||||
self.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(data, ensure_ascii=False, default=str).encode())
|
||||
|
||||
def do_OPTIONS(self):
|
||||
self._json({})
|
||||
|
||||
def do_GET(self):
|
||||
path = urlparse(self.path).path
|
||||
if path == '/api/health':
|
||||
self._json({'status': 'ok', 'version': '6.6.0', 'modules': 'KP/Synastry/Prashna/Remedies/PMC/SadeSati'})
|
||||
elif path == '/api/cities':
|
||||
self._json(list(CITY_DB.keys()))
|
||||
else:
|
||||
self._json({'error': 'Not found'}, 404)
|
||||
|
||||
def do_POST(self):
|
||||
path = urlparse(self.path).path
|
||||
length = int(self.headers.get('Content-Length', 0))
|
||||
body = json.loads(self.rfile.read(length)) if length > 0 else {}
|
||||
|
||||
try:
|
||||
if path == '/api/chart':
|
||||
result = self._compute_chart(body)
|
||||
self._json(result)
|
||||
elif path == '/api/remedies':
|
||||
result = self._compute_remedies(body)
|
||||
self._json(result)
|
||||
elif path == '/api/kp':
|
||||
result = self._compute_kp(body)
|
||||
self._json(result)
|
||||
elif path == '/api/prashna':
|
||||
result = self._compute_prashna(body)
|
||||
self._json(result)
|
||||
elif path == '/api/synastry':
|
||||
result = self._compute_synastry(body)
|
||||
self._json(result)
|
||||
elif path == '/api/sade_sati':
|
||||
result = self._compute_sade_sati(body)
|
||||
self._json(result)
|
||||
elif path == '/api/pancha_mahapurusha':
|
||||
result = self._compute_pmc(body)
|
||||
self._json(result)
|
||||
elif path == '/api/career':
|
||||
result = self._compute_career(body)
|
||||
self._json(result)
|
||||
elif path == '/api/relationship':
|
||||
result = self._compute_relationship(body)
|
||||
self._json(result)
|
||||
else:
|
||||
self._json({'error': f'Unknown endpoint: {path}'}, 404)
|
||||
except Exception as e:
|
||||
self._json({'error': str(e)}, 500)
|
||||
|
||||
def _compute_chart(self, body):
|
||||
"""完整星盘计算"""
|
||||
year = int(body.get('year', 1990))
|
||||
month = int(body.get('month', 6))
|
||||
day = int(body.get('day', 15))
|
||||
hour = float(body.get('hour', 12))
|
||||
minute = float(body.get('minute', 0))
|
||||
lat = float(body.get('lat', 39.9))
|
||||
lon = float(body.get('lon', 116.4))
|
||||
tz = float(body.get('tz', 8))
|
||||
|
||||
try:
|
||||
import swisseph as swe
|
||||
swe.set_ephe_path(os.path.join(SCRIPTS_DIR, '..', 'swiss_ephemeris'))
|
||||
jd = swe.julday(year, month, day, hour + minute/60.0)
|
||||
swe.set_sid_mode(swe.SIDM_LAHIRI, 0, 0)
|
||||
|
||||
planets_data = {}
|
||||
planet_ids = {'Sun': 0, 'Moon': 1, 'Mars': 4, 'Mercury': 2, 'Jupiter': 5, 'Venus': 3, 'Saturn': 6, 'Rahu': 10, 'Ketu': 20}
|
||||
planet_names_rev = {v: k for k, v in planet_ids.items()}
|
||||
|
||||
for pid, pname in planet_names_rev.items():
|
||||
if pid == 20:
|
||||
lon_rahu, _ = swe.calc_ut(jd, 10)
|
||||
lon = (lon_rahu[0] + 180) % 360
|
||||
else:
|
||||
result, _ = swe.calc_ut(jd, pid)
|
||||
lon = result[0] % 360
|
||||
sign_idx = int(lon / 30) % 12
|
||||
planets_data[pname] = {'lon': lon, 'sign_idx': sign_idx, 'sign': SIGNS[sign_idx], 'degree': lon % 30}
|
||||
|
||||
# Ascendant
|
||||
asc_lon = swe.houses_ex(jd, lat, lon, b'E')[0][0] % 360
|
||||
asc_sign_idx = int(asc_lon / 30) % 12
|
||||
asc_sign = SIGNS[asc_sign_idx]
|
||||
|
||||
# Houses
|
||||
houses = {}
|
||||
for h in range(1, 13):
|
||||
s = (asc_sign_idx + h - 1) % 12
|
||||
houses[h] = {'sign': SIGNS[s], 'sign_idx': s}
|
||||
|
||||
# Planet houses
|
||||
for pn, pd in planets_data.items():
|
||||
pd['house'] = ((pd['sign_idx'] - asc_sign_idx) % 12) + 1
|
||||
|
||||
# Dasha (simplified Vimshottari)
|
||||
moon_lon = planets_data['Moon']['lon']
|
||||
nak_size = 360/27
|
||||
nak_idx = int(moon_lon / nak_size)
|
||||
dasha_lords = ['Ketu','Venus','Sun','Moon','Mars','Rahu','Jupiter','Saturn','Mercury']
|
||||
dasha_years = [7,20,6,10,7,18,16,19,17]
|
||||
nak_lord_idx = nak_idx % 9
|
||||
md_lord = dasha_lords[nak_lord_idx]
|
||||
total_years = dasha_years[nak_lord_idx]
|
||||
elapsed = (moon_lon % nak_size) / nak_size * total_years
|
||||
remaining = total_years - elapsed
|
||||
|
||||
birth_dt = datetime(year, month, day, int(hour), int(minute))
|
||||
elapsed_days = elapsed * 365.25636
|
||||
dasha_start = birth_dt - timedelta(days=elapsed_days) if elapsed_days < 365*120 else birth_dt
|
||||
|
||||
# Yoga detection
|
||||
yogas = self._detect_yogas(planets_data, asc_sign_idx)
|
||||
|
||||
# Sade Sati
|
||||
from sade_sati import calc_sade_sati_complete
|
||||
# Transit Saturn (approximate)
|
||||
saturn_year_progress = (year - 2026) * 12 / 30 # ~12 signs in 30 years
|
||||
transit_saturn_sign = (planets_data['Saturn']['sign_idx'] + int(saturn_year_progress)) % 12
|
||||
transit_saturn_lon = transit_saturn_sign * 30 + 15
|
||||
sade_sati = calc_sade_sati_complete(moon_lon, asc_lon, transit_saturn_lon)
|
||||
|
||||
# Dasha清单
|
||||
from extended_dashas import get_available_dashas, DASHA_REGISTRY
|
||||
dashas = get_available_dashas()
|
||||
dasha_list = [{'key': k, 'name': DASHA_REGISTRY[k]['name'], 'years': DASHA_REGISTRY[k]['years'], 'type': DASHA_REGISTRY[k]['type']} for k in dashas]
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'version': '6.6.0',
|
||||
'birth': {'date': f'{year}-{month:02d}-{day:02d}', 'time': f'{int(hour):02d}:{int(minute):02d}'},
|
||||
'ascendant': {'sign': asc_sign, 'sign_idx': asc_sign_idx, 'degree': round(asc_lon % 30, 2)},
|
||||
'planets': planets_data,
|
||||
'houses': houses,
|
||||
'dasha': {
|
||||
'current_md': md_lord,
|
||||
'remaining_years': round(remaining, 2),
|
||||
'total_years': total_years,
|
||||
'start_date': dasha_start.isoformat() if hasattr(dasha_start, 'isoformat') else str(dasha_start),
|
||||
},
|
||||
'yogas': yogas,
|
||||
'sade_sati': sade_sati,
|
||||
'available_dashas': dasha_list,
|
||||
'dasha_count': len(dasha_list),
|
||||
}
|
||||
except ImportError:
|
||||
return self._fallback_chart(year, month, day, hour, minute, lat, lon, tz)
|
||||
|
||||
def _fallback_chart(self, year, month, day, hour, minute, lat, lon, tz):
|
||||
"""无Swiss Ephemeris时的简化计算"""
|
||||
import hashlib
|
||||
seed = int(hashlib.md5(f"{year}{month}{day}{hour}{minute}{lat}{lon}".encode()).hexdigest()[:8], 16)
|
||||
asc_sign_idx = seed % 12
|
||||
asc_sign = SIGNS[asc_sign_idx]
|
||||
|
||||
planets = {}
|
||||
planet_names = ['Sun','Moon','Mars','Mercury','Jupiter','Venus','Saturn','Rahu','Ketu']
|
||||
import random
|
||||
rng = random.Random(seed)
|
||||
for pn in planet_names:
|
||||
sign_idx = (asc_sign_idx + rng.randint(0, 11)) % 12
|
||||
deg = rng.uniform(0, 30)
|
||||
planets[pn] = {
|
||||
'sign': SIGNS[sign_idx], 'sign_idx': sign_idx,
|
||||
'degree': deg, 'lon': sign_idx * 30 + deg,
|
||||
'house': ((sign_idx - asc_sign_idx) % 12) + 1,
|
||||
}
|
||||
|
||||
houses = {}
|
||||
for h in range(1, 13):
|
||||
s = (asc_sign_idx + h - 1) % 12
|
||||
houses[h] = {'sign': SIGNS[s], 'sign_idx': s}
|
||||
|
||||
return {
|
||||
'success': True, 'version': '6.6.0-fallback',
|
||||
'warning': 'Swiss Ephemeris未安装,使用简化计算',
|
||||
'ascendant': {'sign': asc_sign, 'sign_idx': asc_sign_idx},
|
||||
'planets': planets, 'houses': houses,
|
||||
'dasha': {'current_md': 'Moon', 'remaining_years': 5},
|
||||
'yogas': [], 'sade_sati': {'active': False},
|
||||
'available_dashas': [], 'dasha_count': 0,
|
||||
}
|
||||
|
||||
def _detect_yogas(self, planets, asc_idx):
|
||||
yogas = []
|
||||
KENDRA = {1,4,7,10}
|
||||
try:
|
||||
from pancha_mahapurusha import detect_pancha_mahapurusha
|
||||
pmc = detect_pancha_mahapurusha(planets)
|
||||
for y in pmc:
|
||||
if y['is_valid']:
|
||||
yogas.append({'name': y['name'], 'planets': [y['planet']], 'category': 'PMC'})
|
||||
except: pass
|
||||
|
||||
try:
|
||||
from yoga_expansion import detect_all_yogas as detect_yogas_ext
|
||||
for y in detect_yogas_ext(planets, SIGNS[asc_idx]):
|
||||
yogas.append({'name': y.get('name',''), 'planets': y.get('planets',[]), 'category': 'extended'})
|
||||
except: pass
|
||||
|
||||
return yogas[:10]
|
||||
|
||||
def _compute_remedies(self, body):
|
||||
from remedies import recommend_remedies
|
||||
shadbala = body.get('shadbala', {})
|
||||
doshas = body.get('doshas', [])
|
||||
dasha_lord = body.get('dasha_lord', '')
|
||||
return recommend_remedies(shadbala, doshas=doshas, active_dasha_lord=dasha_lord)
|
||||
|
||||
def _compute_kp(self, body):
|
||||
planets = body.get('planets', {})
|
||||
asc_idx = body.get('asc_sign_idx', 0)
|
||||
from kp_system import calc_kp_analysis
|
||||
return calc_kp_analysis(planets, SIGNS[asc_idx])
|
||||
|
||||
def _compute_prashna(self, body):
|
||||
question_type = body.get('question', 'general')
|
||||
from prashna import calc_prashna_chart, get_kp_prashna_answer
|
||||
from datetime import datetime, timedelta
|
||||
chart = calc_prashna_chart(datetime.now(), body.get('planets', {}))
|
||||
answer = get_kp_prashna_answer(body.get('planets', {}), question_type, 15.5)
|
||||
return {'prashna_chart': chart, 'kp_answer': answer}
|
||||
|
||||
def _compute_synastry(self, body):
|
||||
from synastry import calc_ashtakoot
|
||||
return calc_ashtakoot(body.get('male_moon', 0), body.get('female_moon', 0))
|
||||
|
||||
def _compute_sade_sati(self, body):
|
||||
from sade_sati import calc_sade_sati_complete
|
||||
return calc_sade_sati_complete(body.get('moon_degree', 0), body.get('asc_degree', 0), body.get('saturn_degree', 0))
|
||||
|
||||
def _compute_pmc(self, body):
|
||||
from pancha_mahapurusha import assess_pmc_strength
|
||||
return assess_pmc_strength(body.get('planets', {}), body.get('sun_degree'))
|
||||
|
||||
def _compute_career(self, body):
|
||||
from career_analysis import analyze_career
|
||||
return analyze_career(body.get('planets', {}), body.get('asc_sign', 'Aries'))
|
||||
|
||||
def _compute_relationship(self, body):
|
||||
from relationship_analysis import analyze_relationship
|
||||
return analyze_relationship(body.get('planets', {}), body.get('asc_sign', 'Aries'))
|
||||
|
||||
|
||||
def start_server(port=5200):
|
||||
server = HTTPServer(('0.0.0.0', port), JyotishAPIHandler)
|
||||
print(f'🔮 Jyotish API v6.6.0 running on http://localhost:{port}')
|
||||
print(f' POST /api/chart — 完整星盘计算')
|
||||
print(f' POST /api/remedies — 补救建议')
|
||||
print(f' POST /api/kp — KP分析')
|
||||
print(f' POST /api/prashna — 卜卦')
|
||||
print(f' POST /api/synastry — 合盘')
|
||||
print(f' POST /api/sade_sati — 土星周期')
|
||||
print(f' POST /api/pancha_mahapurusha — 五王瑜伽')
|
||||
print(f' POST /api/career — 事业分析')
|
||||
print(f' POST /api/relationship — 感情分析')
|
||||
print(f' GET /api/health — 健康检查')
|
||||
print(f' GET /api/cities — 城市列表')
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = int(sys.argv[2]) if len(sys.argv) > 2 and sys.argv[1] == '--port' else 5200
|
||||
start_server(port)
|
||||
Reference in New Issue
Block a user