Spaces:
Running
Running
th commited on
Commit ·
76b1cf2
1
Parent(s): cf8055d
fix: 鉴权fail-closed + 44端点async→def + Dockerfile锁依赖commit
Browse files安全: 移除硬编码默认key fallback(sisi_default_key_change_me)。
API_KEY/SISI_HF_API_KEY均未配置时启动记录error日志,所有受保护
端点返回503拒绝服务,不再接受可猜测的默认key。
性能: 44个async def端点全部改为def(FastAPI线程池)。全文件零await,
纯同步CPU计算跑在async def里会阻塞uvicorn事件循环,单worker下
并发请求互相卡死(与ziwei API同类问题,badbcb4)。
供应链: Dockerfile克隆china-testing/bazi锁定到commit 7150d5b
(2026-07-09 HEAD),上游变更/删库不再影响生产构建。
冒烟测试: 未配置key→503(任意key), 错误key→403, 正确key→200
(/api/qimen/now)。语法/导入均过。
🦊 Generated with Sisi
- Dockerfile +4 -2
- app.py +59 -46
Dockerfile
CHANGED
|
@@ -15,8 +15,10 @@ COPY requirements.txt .
|
|
| 15 |
# Install Python dependencies
|
| 16 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 17 |
|
| 18 |
-
# Clone the bazi library
|
| 19 |
-
|
|
|
|
|
|
|
| 20 |
|
| 21 |
# Copy all application code
|
| 22 |
COPY *.py .
|
|
|
|
| 15 |
# Install Python dependencies
|
| 16 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 17 |
|
| 18 |
+
# Clone the bazi library — pinned to a fixed commit (2026-07-09) so upstream
|
| 19 |
+
# changes/deletions can't silently alter or break our production builds
|
| 20 |
+
RUN git clone https://github.com/china-testing/bazi.git /app/bazi_lib \
|
| 21 |
+
&& git -C /app/bazi_lib checkout 7150d5b6fba5e563dd0751b957dc990bb84ab6f0
|
| 22 |
|
| 23 |
# Copy all application code
|
| 24 |
COPY *.py .
|
app.py
CHANGED
|
@@ -59,11 +59,24 @@ logger = logging.getLogger(__name__)
|
|
| 59 |
# Support both naming conventions:
|
| 60 |
# - API_KEY: For HuggingFace Space settings (simple, since only one API key)
|
| 61 |
# - SISI_HF_API_KEY: For Cloudflare (clear distinction among many API keys)
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
|
| 65 |
def verify_api_key(x_api_key: Optional[str] = Header(None)):
|
| 66 |
-
"""Verify API key from request header"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
if x_api_key != API_KEY:
|
| 68 |
raise HTTPException(
|
| 69 |
status_code=403,
|
|
@@ -649,7 +662,7 @@ def health_check():
|
|
| 649 |
|
| 650 |
@app.post("/calculate-bazi")
|
| 651 |
@app.post("/api/calculate-bazi") # Alternative endpoint
|
| 652 |
-
|
| 653 |
"""
|
| 654 |
Calculate BaZi (八字) chart from birth information
|
| 655 |
|
|
@@ -727,7 +740,7 @@ async def calculate_bazi(req: BaZiRequest, api_key: str = Depends(verify_api_key
|
|
| 727 |
|
| 728 |
|
| 729 |
@app.post("/calculate-bazi-simple")
|
| 730 |
-
|
| 731 |
"""
|
| 732 |
Simplified BaZi calculation - returns only essential data
|
| 733 |
|
|
@@ -769,7 +782,7 @@ async def calculate_bazi_simple(req: BaZiRequest, api_key: str = Depends(verify_
|
|
| 769 |
|
| 770 |
@app.post("/calculate-bazi-complete")
|
| 771 |
@app.post("/api/calculate-bazi-complete") # Alternative endpoint
|
| 772 |
-
|
| 773 |
"""
|
| 774 |
Calculate complete BaZi with 大运 (Major Cycles) and 流年 (Yearly Cycles)
|
| 775 |
|
|
@@ -869,7 +882,7 @@ async def calculate_bazi_complete(req: BaZiCompleteRequest, api_key: str = Depen
|
|
| 869 |
|
| 870 |
@app.post("/analyze-shensha")
|
| 871 |
@app.post("/api/analyze-shensha") # Alternative endpoint
|
| 872 |
-
|
| 873 |
"""
|
| 874 |
🔮 Analyze Spiritual Forces (神煞分析) - Advanced Feature
|
| 875 |
|
|
@@ -1026,7 +1039,7 @@ async def analyze_shensha(req: BaZiRequest, api_key: str = Depends(verify_api_ke
|
|
| 1026 |
|
| 1027 |
@app.post("/analyze-genju")
|
| 1028 |
@app.post("/api/analyze-genju") # Alternative endpoint
|
| 1029 |
-
|
| 1030 |
"""
|
| 1031 |
🎯 Analyze Life Pattern (格局分析) - Core Premium Feature
|
| 1032 |
|
|
@@ -1211,7 +1224,7 @@ async def analyze_genju(req: BaZiRequest, api_key: str = Depends(verify_api_key)
|
|
| 1211 |
|
| 1212 |
@app.post("/analyze-dayun")
|
| 1213 |
@app.post("/api/analyze-dayun") # Alternative endpoint
|
| 1214 |
-
|
| 1215 |
"""
|
| 1216 |
📅 Analyze Major Cycles (大运分析) - Premium Fortune Prediction
|
| 1217 |
|
|
@@ -1472,7 +1485,7 @@ async def analyze_dayun(req: BaZiCompleteRequest, api_key: str = Depends(verify_
|
|
| 1472 |
|
| 1473 |
@app.post("/ai-interpretation")
|
| 1474 |
@app.post("/api/ai-interpretation") # Alternative endpoint
|
| 1475 |
-
|
| 1476 |
"""
|
| 1477 |
🤖 AI BaZi Interpretation - Transform Technical Analysis into Natural Language
|
| 1478 |
|
|
@@ -1751,7 +1764,7 @@ async def ai_interpretation(req: BaZiInterpretationRequest, api_key: str = Depen
|
|
| 1751 |
|
| 1752 |
@app.post("/monthly-fortune")
|
| 1753 |
@app.post("/api/monthly-fortune") # Alternative endpoint
|
| 1754 |
-
|
| 1755 |
"""
|
| 1756 |
📅 Monthly Fortune Analysis (流月运势分析)
|
| 1757 |
|
|
@@ -1828,7 +1841,7 @@ async def analyze_monthly_fortune_api(req: MonthlyFortuneRequest, api_key: str =
|
|
| 1828 |
|
| 1829 |
@app.post("/career-monthly-fortune")
|
| 1830 |
@app.post("/api/career-monthly-fortune") # Alternative endpoint
|
| 1831 |
-
|
| 1832 |
"""
|
| 1833 |
💼 Career-Specific Monthly Fortune Analysis (事业月运分析)
|
| 1834 |
|
|
@@ -1898,7 +1911,7 @@ async def analyze_career_monthly_fortune_api(req: CareerMonthlyFortuneRequest, a
|
|
| 1898 |
|
| 1899 |
@app.post("/yearly-fortune")
|
| 1900 |
@app.post("/api/yearly-fortune") # Alternative endpoint
|
| 1901 |
-
|
| 1902 |
"""
|
| 1903 |
🎯 Yearly Fortune Analysis - 12 Month Complete Forecast (流年12个月运势)
|
| 1904 |
|
|
@@ -2025,7 +2038,7 @@ async def analyze_yearly_fortune_api(req: YearlyFortuneRequest, api_key: str = D
|
|
| 2025 |
|
| 2026 |
@app.post("/daily-fortune")
|
| 2027 |
@app.post("/api/daily-fortune") # Alternative endpoint
|
| 2028 |
-
|
| 2029 |
"""
|
| 2030 |
🗓️ Daily Fortune & Date Selection (流日择日分析)
|
| 2031 |
|
|
@@ -2103,7 +2116,7 @@ async def analyze_daily_fortune_api(req: DailyFortuneRequest, api_key: str = Dep
|
|
| 2103 |
|
| 2104 |
@app.post("/hourly-fortune")
|
| 2105 |
@app.post("/api/hourly-fortune") # Alternative endpoint
|
| 2106 |
-
|
| 2107 |
"""
|
| 2108 |
⏰ Hourly Fortune Analysis (时辰吉凶分析)
|
| 2109 |
|
|
@@ -2179,7 +2192,7 @@ async def analyze_hourly_fortune_api(req: DailyFortuneRequest, api_key: str = De
|
|
| 2179 |
|
| 2180 |
@app.post("/find-auspicious-dates")
|
| 2181 |
@app.post("/api/find-auspicious-dates") # Alternative endpoint
|
| 2182 |
-
|
| 2183 |
"""
|
| 2184 |
🔍 Find Auspicious Dates (寻找吉日)
|
| 2185 |
|
|
@@ -2284,7 +2297,7 @@ async def find_auspicious_dates_api(req: FindAuspiciousDatesRequest, api_key: st
|
|
| 2284 |
# ==================== Chinese Calendar API ====================
|
| 2285 |
|
| 2286 |
@app.get("/api/calendar/today")
|
| 2287 |
-
|
| 2288 |
"""
|
| 2289 |
Get today's Chinese lunar calendar information
|
| 2290 |
|
|
@@ -2346,7 +2359,7 @@ async def get_today_calendar():
|
|
| 2346 |
|
| 2347 |
|
| 2348 |
@app.get("/api/calendar/range")
|
| 2349 |
-
|
| 2350 |
"""
|
| 2351 |
Get Chinese lunar calendar information for a date range
|
| 2352 |
|
|
@@ -2408,7 +2421,7 @@ async def get_calendar_range(start: str, end: str):
|
|
| 2408 |
|
| 2409 |
|
| 2410 |
@app.get("/api/calendar/{date_str}")
|
| 2411 |
-
|
| 2412 |
"""
|
| 2413 |
Get Chinese lunar calendar information for a specific date
|
| 2414 |
|
|
@@ -2458,7 +2471,7 @@ class LunarToSolarRequest(BaseModel):
|
|
| 2458 |
|
| 2459 |
|
| 2460 |
@app.post("/api/calendar/convert-lunar-to-solar")
|
| 2461 |
-
|
| 2462 |
"""
|
| 2463 |
Convert Chinese Lunar calendar date to Gregorian (Solar) calendar date
|
| 2464 |
|
|
@@ -2544,7 +2557,7 @@ class NineStarsRequest(BaseModel):
|
|
| 2544 |
|
| 2545 |
|
| 2546 |
@app.post("/api/nine-stars/analyze")
|
| 2547 |
-
|
| 2548 |
req: NineStarsRequest,
|
| 2549 |
api_key: str = Depends(verify_api_key)
|
| 2550 |
):
|
|
@@ -2649,7 +2662,7 @@ async def analyze_nine_stars(
|
|
| 2649 |
|
| 2650 |
|
| 2651 |
@app.get("/api/nine-stars/today")
|
| 2652 |
-
|
| 2653 |
hour: int = 12,
|
| 2654 |
api_key: str = Depends(verify_api_key)
|
| 2655 |
):
|
|
@@ -2693,7 +2706,7 @@ class Constellation28Request(BaseModel):
|
|
| 2693 |
|
| 2694 |
|
| 2695 |
@app.post("/api/28-constellations/analyze")
|
| 2696 |
-
|
| 2697 |
req: Constellation28Request,
|
| 2698 |
api_key: str = Depends(verify_api_key)
|
| 2699 |
):
|
|
@@ -2796,7 +2809,7 @@ async def analyze_28_constellations(
|
|
| 2796 |
|
| 2797 |
|
| 2798 |
@app.get("/api/28-constellations/today")
|
| 2799 |
-
|
| 2800 |
"""
|
| 2801 |
⭐ Get today's 28 Lunar Mansions constellation
|
| 2802 |
|
|
@@ -2829,7 +2842,7 @@ async def get_today_constellation(api_key: str = Depends(verify_api_key)):
|
|
| 2829 |
|
| 2830 |
|
| 2831 |
@app.post("/api/28-constellations/find-auspicious")
|
| 2832 |
-
|
| 2833 |
activity: str,
|
| 2834 |
start_date: str,
|
| 2835 |
end_date: str,
|
|
@@ -2921,7 +2934,7 @@ from zodiac_fortune_service import ZodiacFortuneService
|
|
| 2921 |
|
| 2922 |
|
| 2923 |
@app.get("/api/zodiac-fortune/today/{zodiac}")
|
| 2924 |
-
|
| 2925 |
"""
|
| 2926 |
🐉 Get today's fortune for a specific zodiac (今日生肖运程)
|
| 2927 |
|
|
@@ -2971,7 +2984,7 @@ async def get_today_zodiac_fortune(zodiac: str):
|
|
| 2971 |
|
| 2972 |
|
| 2973 |
@app.get("/api/zodiac-fortune/{zodiac}/{date_str}")
|
| 2974 |
-
|
| 2975 |
"""
|
| 2976 |
🐉 Get fortune for a specific zodiac on a specific date (指定日期生肖运程)
|
| 2977 |
|
|
@@ -3014,7 +3027,7 @@ async def get_zodiac_fortune_by_date(zodiac: str, date_str: str):
|
|
| 3014 |
|
| 3015 |
|
| 3016 |
@app.get("/api/zodiac-fortune/all/{date_str}")
|
| 3017 |
-
|
| 3018 |
"""
|
| 3019 |
🐉 Get fortune for ALL 12 zodiacs on a specific date (12生肖运程)
|
| 3020 |
|
|
@@ -3117,7 +3130,7 @@ class MarriageCompatibilityRequest(BaseModel):
|
|
| 3117 |
|
| 3118 |
@app.post("/api/marriage-compatibility")
|
| 3119 |
@app.post("/marriage-compatibility")
|
| 3120 |
-
|
| 3121 |
req: MarriageCompatibilityRequest,
|
| 3122 |
api_key: str = Depends(verify_api_key)
|
| 3123 |
):
|
|
@@ -3243,7 +3256,7 @@ class FortuneScoreRequest(BaseModel):
|
|
| 3243 |
|
| 3244 |
@app.post("/api/fortune-score")
|
| 3245 |
@app.post("/fortune-score")
|
| 3246 |
-
|
| 3247 |
req: FortuneScoreRequest,
|
| 3248 |
api_key: str = Depends(verify_api_key)
|
| 3249 |
):
|
|
@@ -3344,7 +3357,7 @@ class RitualRecommendRequest(BaseModel):
|
|
| 3344 |
|
| 3345 |
@app.get("/rituals")
|
| 3346 |
@app.get("/api/rituals") # 备用路由
|
| 3347 |
-
|
| 3348 |
"""
|
| 3349 |
获取所有能量仪式
|
| 3350 |
|
|
@@ -3386,7 +3399,7 @@ async def get_all_rituals(api_key: str = Depends(verify_api_key)):
|
|
| 3386 |
|
| 3387 |
@app.get("/rituals/{ritual_id}")
|
| 3388 |
@app.get("/api/rituals/{ritual_id}") # 备用路由
|
| 3389 |
-
|
| 3390 |
"""
|
| 3391 |
获取单个仪式详情
|
| 3392 |
|
|
@@ -3435,7 +3448,7 @@ async def get_ritual_by_id(ritual_id: str, api_key: str = Depends(verify_api_key
|
|
| 3435 |
|
| 3436 |
@app.post("/rituals/search")
|
| 3437 |
@app.post("/api/rituals/search") # 备用路由
|
| 3438 |
-
|
| 3439 |
"""
|
| 3440 |
搜索仪式
|
| 3441 |
|
|
@@ -3505,7 +3518,7 @@ async def search_rituals(request: RitualSearchRequest, api_key: str = Depends(ve
|
|
| 3505 |
|
| 3506 |
@app.get("/rituals/category/{category}")
|
| 3507 |
@app.get("/api/rituals/category/{category}") # 备用路由
|
| 3508 |
-
|
| 3509 |
"""
|
| 3510 |
按类别获取仪式
|
| 3511 |
|
|
@@ -3549,7 +3562,7 @@ async def get_rituals_by_category(category: str, api_key: str = Depends(verify_a
|
|
| 3549 |
|
| 3550 |
@app.get("/rituals/moon-phase/current")
|
| 3551 |
@app.get("/api/rituals/moon-phase/current") # 备用路由
|
| 3552 |
-
|
| 3553 |
"""
|
| 3554 |
获取当前月相适合的仪式
|
| 3555 |
|
|
@@ -3587,7 +3600,7 @@ async def get_current_moon_phase_rituals(api_key: str = Depends(verify_api_key))
|
|
| 3587 |
|
| 3588 |
@app.post("/rituals/recommend")
|
| 3589 |
@app.post("/api/rituals/recommend") # 备用路由
|
| 3590 |
-
|
| 3591 |
"""
|
| 3592 |
个性化仪式推荐
|
| 3593 |
|
|
@@ -3652,7 +3665,7 @@ async def recommend_rituals(request: RitualRecommendRequest, api_key: str = Depe
|
|
| 3652 |
|
| 3653 |
@app.get("/rituals/related/{ritual_id}")
|
| 3654 |
@app.get("/api/rituals/related/{ritual_id}") # 备用路由
|
| 3655 |
-
|
| 3656 |
"""
|
| 3657 |
获取相关仪式
|
| 3658 |
|
|
@@ -3697,7 +3710,7 @@ async def get_related_rituals(ritual_id: str, limit: int = 5, api_key: str = Dep
|
|
| 3697 |
|
| 3698 |
@app.get("/rituals/statistics")
|
| 3699 |
@app.get("/api/rituals/statistics") # 备用路由
|
| 3700 |
-
|
| 3701 |
"""
|
| 3702 |
获取仪式统计信息
|
| 3703 |
|
|
@@ -3750,7 +3763,7 @@ class BodyReadingRequest(BaseModel):
|
|
| 3750 |
|
| 3751 |
@app.post("/analyze-body-reading")
|
| 3752 |
@app.post("/api/analyze-body-reading")
|
| 3753 |
-
|
| 3754 |
req: BodyReadingRequest,
|
| 3755 |
api_key: str = Depends(verify_api_key)
|
| 3756 |
):
|
|
@@ -3846,7 +3859,7 @@ class MarriageDestinyRequest(BaseModel):
|
|
| 3846 |
|
| 3847 |
@app.post("/analyze-marriage-destiny")
|
| 3848 |
@app.post("/api/analyze-marriage-destiny")
|
| 3849 |
-
|
| 3850 |
req: MarriageDestinyRequest,
|
| 3851 |
api_key: str = Depends(verify_api_key)
|
| 3852 |
):
|
|
@@ -3961,7 +3974,7 @@ class QimenChartRequest(BaseModel):
|
|
| 3961 |
|
| 3962 |
@app.post("/api/qimen/chart")
|
| 3963 |
@app.post("/qimen-chart")
|
| 3964 |
-
|
| 3965 |
req: QimenChartRequest,
|
| 3966 |
api_key: str = Depends(verify_api_key)
|
| 3967 |
):
|
|
@@ -4022,7 +4035,7 @@ async def calculate_qimen_chart(
|
|
| 4022 |
|
| 4023 |
@app.get("/api/qimen/now")
|
| 4024 |
@app.get("/qimen-now")
|
| 4025 |
-
|
| 4026 |
purpose: str = "综合",
|
| 4027 |
api_key: str = Depends(verify_api_key)
|
| 4028 |
):
|
|
@@ -4089,7 +4102,7 @@ def _liuyao_response(coins, question, purpose) -> dict:
|
|
| 4089 |
|
| 4090 |
@app.post("/api/liuyao/divine")
|
| 4091 |
@app.post("/liuyao-divine")
|
| 4092 |
-
|
| 4093 |
req: LiuYaoRequest,
|
| 4094 |
api_key: str = Depends(verify_api_key)
|
| 4095 |
):
|
|
@@ -4110,7 +4123,7 @@ async def divine_liuyao(
|
|
| 4110 |
|
| 4111 |
@app.get("/api/liuyao/now")
|
| 4112 |
@app.get("/liuyao-now")
|
| 4113 |
-
|
| 4114 |
purpose: str = "综合",
|
| 4115 |
question: str = "",
|
| 4116 |
api_key: str = Depends(verify_api_key)
|
|
@@ -4144,7 +4157,7 @@ class FengshuiMingGuaRequest(BaseModel):
|
|
| 4144 |
|
| 4145 |
@app.post("/api/fengshui/home-analysis")
|
| 4146 |
@app.post("/fengshui-home-analysis")
|
| 4147 |
-
|
| 4148 |
req: FengshuiHomeRequest,
|
| 4149 |
api_key: str = Depends(verify_api_key)
|
| 4150 |
):
|
|
@@ -4166,7 +4179,7 @@ async def fengshui_home_analysis(
|
|
| 4166 |
|
| 4167 |
@app.post("/api/fengshui/ming-gua")
|
| 4168 |
@app.post("/fengshui-ming-gua")
|
| 4169 |
-
|
| 4170 |
req: FengshuiMingGuaRequest,
|
| 4171 |
api_key: str = Depends(verify_api_key)
|
| 4172 |
):
|
|
@@ -4181,7 +4194,7 @@ async def fengshui_ming_gua(
|
|
| 4181 |
|
| 4182 |
|
| 4183 |
@app.get("/api/fengshui/zhai-gua/{facing}")
|
| 4184 |
-
|
| 4185 |
facing: str,
|
| 4186 |
api_key: str = Depends(verify_api_key)
|
| 4187 |
):
|
|
|
|
| 59 |
# Support both naming conventions:
|
| 60 |
# - API_KEY: For HuggingFace Space settings (simple, since only one API key)
|
| 61 |
# - SISI_HF_API_KEY: For Cloudflare (clear distinction among many API keys)
|
| 62 |
+
# Fail closed: no hardcoded fallback — if neither env var is set, all
|
| 63 |
+
# protected endpoints refuse service instead of accepting a default key.
|
| 64 |
+
API_KEY = os.environ.get("API_KEY") or os.environ.get("SISI_HF_API_KEY")
|
| 65 |
+
|
| 66 |
+
if not API_KEY:
|
| 67 |
+
logger.error(
|
| 68 |
+
"🔒 API key is NOT configured (set API_KEY or SISI_HF_API_KEY). "
|
| 69 |
+
"All protected endpoints will return 503 until a key is set."
|
| 70 |
+
)
|
| 71 |
|
| 72 |
|
| 73 |
def verify_api_key(x_api_key: Optional[str] = Header(None)):
|
| 74 |
+
"""Verify API key from request header (fail closed when unconfigured)"""
|
| 75 |
+
if not API_KEY:
|
| 76 |
+
raise HTTPException(
|
| 77 |
+
status_code=503,
|
| 78 |
+
detail="🔒 API key is not configured on the server. Service unavailable."
|
| 79 |
+
)
|
| 80 |
if x_api_key != API_KEY:
|
| 81 |
raise HTTPException(
|
| 82 |
status_code=403,
|
|
|
|
| 662 |
|
| 663 |
@app.post("/calculate-bazi")
|
| 664 |
@app.post("/api/calculate-bazi") # Alternative endpoint
|
| 665 |
+
def calculate_bazi(req: BaZiRequest, api_key: str = Depends(verify_api_key)):
|
| 666 |
"""
|
| 667 |
Calculate BaZi (八字) chart from birth information
|
| 668 |
|
|
|
|
| 740 |
|
| 741 |
|
| 742 |
@app.post("/calculate-bazi-simple")
|
| 743 |
+
def calculate_bazi_simple(req: BaZiRequest, api_key: str = Depends(verify_api_key)):
|
| 744 |
"""
|
| 745 |
Simplified BaZi calculation - returns only essential data
|
| 746 |
|
|
|
|
| 782 |
|
| 783 |
@app.post("/calculate-bazi-complete")
|
| 784 |
@app.post("/api/calculate-bazi-complete") # Alternative endpoint
|
| 785 |
+
def calculate_bazi_complete(req: BaZiCompleteRequest, api_key: str = Depends(verify_api_key)):
|
| 786 |
"""
|
| 787 |
Calculate complete BaZi with 大运 (Major Cycles) and 流年 (Yearly Cycles)
|
| 788 |
|
|
|
|
| 882 |
|
| 883 |
@app.post("/analyze-shensha")
|
| 884 |
@app.post("/api/analyze-shensha") # Alternative endpoint
|
| 885 |
+
def analyze_shensha(req: BaZiRequest, api_key: str = Depends(verify_api_key)):
|
| 886 |
"""
|
| 887 |
🔮 Analyze Spiritual Forces (神煞分析) - Advanced Feature
|
| 888 |
|
|
|
|
| 1039 |
|
| 1040 |
@app.post("/analyze-genju")
|
| 1041 |
@app.post("/api/analyze-genju") # Alternative endpoint
|
| 1042 |
+
def analyze_genju(req: BaZiRequest, api_key: str = Depends(verify_api_key)):
|
| 1043 |
"""
|
| 1044 |
🎯 Analyze Life Pattern (格局分析) - Core Premium Feature
|
| 1045 |
|
|
|
|
| 1224 |
|
| 1225 |
@app.post("/analyze-dayun")
|
| 1226 |
@app.post("/api/analyze-dayun") # Alternative endpoint
|
| 1227 |
+
def analyze_dayun(req: BaZiCompleteRequest, api_key: str = Depends(verify_api_key)):
|
| 1228 |
"""
|
| 1229 |
📅 Analyze Major Cycles (大运分析) - Premium Fortune Prediction
|
| 1230 |
|
|
|
|
| 1485 |
|
| 1486 |
@app.post("/ai-interpretation")
|
| 1487 |
@app.post("/api/ai-interpretation") # Alternative endpoint
|
| 1488 |
+
def ai_interpretation(req: BaZiInterpretationRequest, api_key: str = Depends(verify_api_key)):
|
| 1489 |
"""
|
| 1490 |
🤖 AI BaZi Interpretation - Transform Technical Analysis into Natural Language
|
| 1491 |
|
|
|
|
| 1764 |
|
| 1765 |
@app.post("/monthly-fortune")
|
| 1766 |
@app.post("/api/monthly-fortune") # Alternative endpoint
|
| 1767 |
+
def analyze_monthly_fortune_api(req: MonthlyFortuneRequest, api_key: str = Depends(verify_api_key)):
|
| 1768 |
"""
|
| 1769 |
📅 Monthly Fortune Analysis (流月运势分析)
|
| 1770 |
|
|
|
|
| 1841 |
|
| 1842 |
@app.post("/career-monthly-fortune")
|
| 1843 |
@app.post("/api/career-monthly-fortune") # Alternative endpoint
|
| 1844 |
+
def analyze_career_monthly_fortune_api(req: CareerMonthlyFortuneRequest, api_key: str = Depends(verify_api_key)):
|
| 1845 |
"""
|
| 1846 |
💼 Career-Specific Monthly Fortune Analysis (事业月运分析)
|
| 1847 |
|
|
|
|
| 1911 |
|
| 1912 |
@app.post("/yearly-fortune")
|
| 1913 |
@app.post("/api/yearly-fortune") # Alternative endpoint
|
| 1914 |
+
def analyze_yearly_fortune_api(req: YearlyFortuneRequest, api_key: str = Depends(verify_api_key)):
|
| 1915 |
"""
|
| 1916 |
🎯 Yearly Fortune Analysis - 12 Month Complete Forecast (流年12个月运势)
|
| 1917 |
|
|
|
|
| 2038 |
|
| 2039 |
@app.post("/daily-fortune")
|
| 2040 |
@app.post("/api/daily-fortune") # Alternative endpoint
|
| 2041 |
+
def analyze_daily_fortune_api(req: DailyFortuneRequest, api_key: str = Depends(verify_api_key)):
|
| 2042 |
"""
|
| 2043 |
🗓️ Daily Fortune & Date Selection (流日择日分析)
|
| 2044 |
|
|
|
|
| 2116 |
|
| 2117 |
@app.post("/hourly-fortune")
|
| 2118 |
@app.post("/api/hourly-fortune") # Alternative endpoint
|
| 2119 |
+
def analyze_hourly_fortune_api(req: DailyFortuneRequest, api_key: str = Depends(verify_api_key)):
|
| 2120 |
"""
|
| 2121 |
⏰ Hourly Fortune Analysis (时辰吉凶分析)
|
| 2122 |
|
|
|
|
| 2192 |
|
| 2193 |
@app.post("/find-auspicious-dates")
|
| 2194 |
@app.post("/api/find-auspicious-dates") # Alternative endpoint
|
| 2195 |
+
def find_auspicious_dates_api(req: FindAuspiciousDatesRequest, api_key: str = Depends(verify_api_key)):
|
| 2196 |
"""
|
| 2197 |
🔍 Find Auspicious Dates (寻找吉日)
|
| 2198 |
|
|
|
|
| 2297 |
# ==================== Chinese Calendar API ====================
|
| 2298 |
|
| 2299 |
@app.get("/api/calendar/today")
|
| 2300 |
+
def get_today_calendar():
|
| 2301 |
"""
|
| 2302 |
Get today's Chinese lunar calendar information
|
| 2303 |
|
|
|
|
| 2359 |
|
| 2360 |
|
| 2361 |
@app.get("/api/calendar/range")
|
| 2362 |
+
def get_calendar_range(start: str, end: str):
|
| 2363 |
"""
|
| 2364 |
Get Chinese lunar calendar information for a date range
|
| 2365 |
|
|
|
|
| 2421 |
|
| 2422 |
|
| 2423 |
@app.get("/api/calendar/{date_str}")
|
| 2424 |
+
def get_calendar_by_date(date_str: str):
|
| 2425 |
"""
|
| 2426 |
Get Chinese lunar calendar information for a specific date
|
| 2427 |
|
|
|
|
| 2471 |
|
| 2472 |
|
| 2473 |
@app.post("/api/calendar/convert-lunar-to-solar")
|
| 2474 |
+
def convert_lunar_to_solar(request: LunarToSolarRequest):
|
| 2475 |
"""
|
| 2476 |
Convert Chinese Lunar calendar date to Gregorian (Solar) calendar date
|
| 2477 |
|
|
|
|
| 2557 |
|
| 2558 |
|
| 2559 |
@app.post("/api/nine-stars/analyze")
|
| 2560 |
+
def analyze_nine_stars(
|
| 2561 |
req: NineStarsRequest,
|
| 2562 |
api_key: str = Depends(verify_api_key)
|
| 2563 |
):
|
|
|
|
| 2662 |
|
| 2663 |
|
| 2664 |
@app.get("/api/nine-stars/today")
|
| 2665 |
+
def get_today_nine_stars(
|
| 2666 |
hour: int = 12,
|
| 2667 |
api_key: str = Depends(verify_api_key)
|
| 2668 |
):
|
|
|
|
| 2706 |
|
| 2707 |
|
| 2708 |
@app.post("/api/28-constellations/analyze")
|
| 2709 |
+
def analyze_28_constellations(
|
| 2710 |
req: Constellation28Request,
|
| 2711 |
api_key: str = Depends(verify_api_key)
|
| 2712 |
):
|
|
|
|
| 2809 |
|
| 2810 |
|
| 2811 |
@app.get("/api/28-constellations/today")
|
| 2812 |
+
def get_today_constellation(api_key: str = Depends(verify_api_key)):
|
| 2813 |
"""
|
| 2814 |
⭐ Get today's 28 Lunar Mansions constellation
|
| 2815 |
|
|
|
|
| 2842 |
|
| 2843 |
|
| 2844 |
@app.post("/api/28-constellations/find-auspicious")
|
| 2845 |
+
def find_auspicious_dates(
|
| 2846 |
activity: str,
|
| 2847 |
start_date: str,
|
| 2848 |
end_date: str,
|
|
|
|
| 2934 |
|
| 2935 |
|
| 2936 |
@app.get("/api/zodiac-fortune/today/{zodiac}")
|
| 2937 |
+
def get_today_zodiac_fortune(zodiac: str):
|
| 2938 |
"""
|
| 2939 |
🐉 Get today's fortune for a specific zodiac (今日生肖运程)
|
| 2940 |
|
|
|
|
| 2984 |
|
| 2985 |
|
| 2986 |
@app.get("/api/zodiac-fortune/{zodiac}/{date_str}")
|
| 2987 |
+
def get_zodiac_fortune_by_date(zodiac: str, date_str: str):
|
| 2988 |
"""
|
| 2989 |
🐉 Get fortune for a specific zodiac on a specific date (指定日期生肖运程)
|
| 2990 |
|
|
|
|
| 3027 |
|
| 3028 |
|
| 3029 |
@app.get("/api/zodiac-fortune/all/{date_str}")
|
| 3030 |
+
def get_all_zodiac_fortune(date_str: str):
|
| 3031 |
"""
|
| 3032 |
🐉 Get fortune for ALL 12 zodiacs on a specific date (12生肖运程)
|
| 3033 |
|
|
|
|
| 3130 |
|
| 3131 |
@app.post("/api/marriage-compatibility")
|
| 3132 |
@app.post("/marriage-compatibility")
|
| 3133 |
+
def analyze_marriage_compatibility(
|
| 3134 |
req: MarriageCompatibilityRequest,
|
| 3135 |
api_key: str = Depends(verify_api_key)
|
| 3136 |
):
|
|
|
|
| 3256 |
|
| 3257 |
@app.post("/api/fortune-score")
|
| 3258 |
@app.post("/fortune-score")
|
| 3259 |
+
def calculate_comprehensive_fortune_score(
|
| 3260 |
req: FortuneScoreRequest,
|
| 3261 |
api_key: str = Depends(verify_api_key)
|
| 3262 |
):
|
|
|
|
| 3357 |
|
| 3358 |
@app.get("/rituals")
|
| 3359 |
@app.get("/api/rituals") # 备用路由
|
| 3360 |
+
def get_all_rituals(api_key: str = Depends(verify_api_key)):
|
| 3361 |
"""
|
| 3362 |
获取所有能量仪式
|
| 3363 |
|
|
|
|
| 3399 |
|
| 3400 |
@app.get("/rituals/{ritual_id}")
|
| 3401 |
@app.get("/api/rituals/{ritual_id}") # 备用路由
|
| 3402 |
+
def get_ritual_by_id(ritual_id: str, api_key: str = Depends(verify_api_key)):
|
| 3403 |
"""
|
| 3404 |
获取单个仪式详情
|
| 3405 |
|
|
|
|
| 3448 |
|
| 3449 |
@app.post("/rituals/search")
|
| 3450 |
@app.post("/api/rituals/search") # 备用路由
|
| 3451 |
+
def search_rituals(request: RitualSearchRequest, api_key: str = Depends(verify_api_key)):
|
| 3452 |
"""
|
| 3453 |
搜索仪式
|
| 3454 |
|
|
|
|
| 3518 |
|
| 3519 |
@app.get("/rituals/category/{category}")
|
| 3520 |
@app.get("/api/rituals/category/{category}") # 备用路由
|
| 3521 |
+
def get_rituals_by_category(category: str, api_key: str = Depends(verify_api_key)):
|
| 3522 |
"""
|
| 3523 |
按类别获取仪式
|
| 3524 |
|
|
|
|
| 3562 |
|
| 3563 |
@app.get("/rituals/moon-phase/current")
|
| 3564 |
@app.get("/api/rituals/moon-phase/current") # 备用路由
|
| 3565 |
+
def get_current_moon_phase_rituals(api_key: str = Depends(verify_api_key)):
|
| 3566 |
"""
|
| 3567 |
获取当前月相适合的仪式
|
| 3568 |
|
|
|
|
| 3600 |
|
| 3601 |
@app.post("/rituals/recommend")
|
| 3602 |
@app.post("/api/rituals/recommend") # 备用路由
|
| 3603 |
+
def recommend_rituals(request: RitualRecommendRequest, api_key: str = Depends(verify_api_key)):
|
| 3604 |
"""
|
| 3605 |
个性化仪式推荐
|
| 3606 |
|
|
|
|
| 3665 |
|
| 3666 |
@app.get("/rituals/related/{ritual_id}")
|
| 3667 |
@app.get("/api/rituals/related/{ritual_id}") # 备用路由
|
| 3668 |
+
def get_related_rituals(ritual_id: str, limit: int = 5, api_key: str = Depends(verify_api_key)):
|
| 3669 |
"""
|
| 3670 |
获取相关仪式
|
| 3671 |
|
|
|
|
| 3710 |
|
| 3711 |
@app.get("/rituals/statistics")
|
| 3712 |
@app.get("/api/rituals/statistics") # 备用路由
|
| 3713 |
+
def get_rituals_statistics(api_key: str = Depends(verify_api_key)):
|
| 3714 |
"""
|
| 3715 |
获取仪式统计信息
|
| 3716 |
|
|
|
|
| 3763 |
|
| 3764 |
@app.post("/analyze-body-reading")
|
| 3765 |
@app.post("/api/analyze-body-reading")
|
| 3766 |
+
def analyze_body_reading_endpoint(
|
| 3767 |
req: BodyReadingRequest,
|
| 3768 |
api_key: str = Depends(verify_api_key)
|
| 3769 |
):
|
|
|
|
| 3859 |
|
| 3860 |
@app.post("/analyze-marriage-destiny")
|
| 3861 |
@app.post("/api/analyze-marriage-destiny")
|
| 3862 |
+
def analyze_marriage_destiny(
|
| 3863 |
req: MarriageDestinyRequest,
|
| 3864 |
api_key: str = Depends(verify_api_key)
|
| 3865 |
):
|
|
|
|
| 3974 |
|
| 3975 |
@app.post("/api/qimen/chart")
|
| 3976 |
@app.post("/qimen-chart")
|
| 3977 |
+
def calculate_qimen_chart(
|
| 3978 |
req: QimenChartRequest,
|
| 3979 |
api_key: str = Depends(verify_api_key)
|
| 3980 |
):
|
|
|
|
| 4035 |
|
| 4036 |
@app.get("/api/qimen/now")
|
| 4037 |
@app.get("/qimen-now")
|
| 4038 |
+
def get_qimen_now(
|
| 4039 |
purpose: str = "综合",
|
| 4040 |
api_key: str = Depends(verify_api_key)
|
| 4041 |
):
|
|
|
|
| 4102 |
|
| 4103 |
@app.post("/api/liuyao/divine")
|
| 4104 |
@app.post("/liuyao-divine")
|
| 4105 |
+
def divine_liuyao(
|
| 4106 |
req: LiuYaoRequest,
|
| 4107 |
api_key: str = Depends(verify_api_key)
|
| 4108 |
):
|
|
|
|
| 4123 |
|
| 4124 |
@app.get("/api/liuyao/now")
|
| 4125 |
@app.get("/liuyao-now")
|
| 4126 |
+
def get_liuyao_now(
|
| 4127 |
purpose: str = "综合",
|
| 4128 |
question: str = "",
|
| 4129 |
api_key: str = Depends(verify_api_key)
|
|
|
|
| 4157 |
|
| 4158 |
@app.post("/api/fengshui/home-analysis")
|
| 4159 |
@app.post("/fengshui-home-analysis")
|
| 4160 |
+
def fengshui_home_analysis(
|
| 4161 |
req: FengshuiHomeRequest,
|
| 4162 |
api_key: str = Depends(verify_api_key)
|
| 4163 |
):
|
|
|
|
| 4179 |
|
| 4180 |
@app.post("/api/fengshui/ming-gua")
|
| 4181 |
@app.post("/fengshui-ming-gua")
|
| 4182 |
+
def fengshui_ming_gua(
|
| 4183 |
req: FengshuiMingGuaRequest,
|
| 4184 |
api_key: str = Depends(verify_api_key)
|
| 4185 |
):
|
|
|
|
| 4194 |
|
| 4195 |
|
| 4196 |
@app.get("/api/fengshui/zhai-gua/{facing}")
|
| 4197 |
+
def fengshui_zhai_gua(
|
| 4198 |
facing: str,
|
| 4199 |
api_key: str = Depends(verify_api_key)
|
| 4200 |
):
|