v6.1.10: Package for PyPI — add jyotish_vedic/ package, CLI entry points, fix pyproject.toml

This commit is contained in:
732642856
2026-06-10 13:22:17 +08:00
parent 83c96465c7
commit a66fa3db32
5 changed files with 301 additions and 25 deletions
+155
View File
@@ -0,0 +1,155 @@
"""
Jyotish Vedic Astrology — Comprehensive calculation engine
A Python package for Vedic (Jyotish) astrology calculations:
- D1-D60 divisional charts (Varga)
- Vimshottari Dasha (planetary periods)
- Shadbala (six-fold planetary strength)
- Ashtakavarga (eight-fold bindus)
- Yoga detection (planetary combinations)
- Nakshatra analysis
- Transit calculations
- Full-reading synthesis
License: MIT
"""
import sys
import os
# Add scripts dir to path so all engine modules are importable
_pkg_dir = os.path.dirname(os.path.abspath(__file__))
_repo_root = os.path.dirname(_pkg_dir)
_scripts_dir = os.path.join(_repo_root, "scripts")
if _scripts_dir not in sys.path:
sys.path.insert(0, _scripts_dir)
__version__ = "6.1.10"
__all__ = [
"calculate_chart",
"calculate_dasha",
"calculate_shadbala",
"calculate_ashtakavarga",
"calculate_varga",
"calculate_yogas",
"full_reading",
]
# Lazy imports — only load when called
def _import_engine():
"""Import jyotish_engine module (lazy to avoid heavy init)."""
import jyotish_engine
return jyotish_engine
def calculate_chart(year, month, day, hour, minute, lat, lon, tz, node_mode="mean"):
"""Calculate D1 Rashi chart."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "chart",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def calculate_dasha(year, month, day, hour, minute, lat, lon, tz, years=10, node_mode="mean"):
"""Calculate Vimshottari Dasha timeline."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "dasha",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--years", str(years), "--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def calculate_shadbala(year, month, day, hour, minute, lat, lon, tz, node_mode="mean"):
"""Calculate Shadbala (six-fold strength)."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "shadbala",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def calculate_ashtakavarga(year, month, day, hour, minute, lat, lon, tz, node_mode="mean"):
"""Calculate Ashtakavarga matrix."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "ashtakavarga",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def calculate_varga(year, month, day, hour, minute, lat, lon, tz, varga="D9", node_mode="mean"):
"""Calculate a specific Varga (D9, D10, etc.)."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "varga",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--varga", varga, "--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def calculate_yogas(year, month, day, hour, minute, lat, lon, tz, node_mode="mean"):
"""Detect Yogas in the birth chart."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "yoga",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
def full_reading(year, month, day, hour, minute, lat, lon, tz, age, transit_date, node_mode="mean"):
"""Run the complete full-reading pipeline."""
import json
import subprocess
engine = os.path.join(_scripts_dir, "jyotish_engine.py")
cmd = [
sys.executable, engine, "full-reading",
"--year", str(year), "--month", str(month), "--day", str(day),
"--hour", str(hour), "--minute", str(minute),
"--lat", str(lat), "--lon", str(lon), "--tz", str(tz),
"--age", str(age), "--transit-date", transit_date,
"--node-mode", node_mode,
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
return json.loads(result.stdout) if result.returncode == 0 else {"error": result.stderr}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env python3
"""
Jyotish CLI entry point.
Usage: jyotish <command> [args]
"""
import sys
import os
SCRIPT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "scripts")
def main():
"""Delegate to jyotish_engine.py CLI."""
engine = os.path.join(SCRIPT_DIR, "jyotish_engine.py")
if not os.path.exists(engine):
print(f"Error: Engine not found at {engine}", file=sys.stderr)
sys.exit(1)
# Pass all args after 'jyotish' to the engine
cmd = [sys.executable, engine] + sys.argv[1:]
os.execv(sys.executable, cmd)
if __name__ == "__main__":
main()
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""
Jyotish Engine CLI wrapper.
Usage: jyotish-engine <command> [args]
"""
import sys
import os
SCRIPT_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "scripts")
def cli_main():
"""Delegate to jyotish_engine.py CLI."""
engine = os.path.join(SCRIPT_DIR, "jyotish_engine.py")
if not os.path.exists(engine):
print(f"Error: Engine not found at {engine}", file=sys.stderr)
sys.exit(1)
cmd = [sys.executable, engine] + sys.argv[1:]
os.execv(sys.executable, cmd)
if __name__ == "__main__":
cli_main()
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""
Jyotish MCP Server entry point.
Usage: jyotish-mcp
"""
import sys
import os
# The actual MCP server is at repo root; delegate to it
_repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_mcp_server = os.path.join(_repo_root, "mcp_server.py")
def main():
"""Run the MCP server."""
if not os.path.exists(_mcp_server):
print(f"Error: MCP server not found at {_mcp_server}", file=sys.stderr)
sys.exit(1)
# Execute the root-level MCP server
with open(_mcp_server, "r", encoding="utf-8") as f:
code = compile(f.read(), _mcp_server, "exec")
exec(code, {"__file__": _mcp_server, "__name__": "__main__"})
if __name__ == "__main__":
main()
+70 -25
View File
@@ -1,37 +1,82 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "jyotish-vedic-astrology-skill"
version = "6.0.33"
description = "Jyotish WorkBuddy skill calculation engine and validation suite"
name = "jyotish-vedic-astrology"
version = "6.1.10"
description = "Comprehensive Jyotish (Vedic Astrology) calculation engine with AI-ready APIs"
readme = "README.md"
license = "MIT"
requires-python = ">=3.11"
authors = [
{name = "732642856", email = "dev@yinduzhanxing.local"},
]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Astronomy",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Religion and Philosophy :: Astrology",
]
keywords = ["jyotish", "vedic", "astrology", "astronomy", "dasha", "varga", "nakshatra", "shadbala", "panchanga", "horoscope", "birth-chart"]
dependencies = [
"pyswisseph",
"pyswisseph>=2.8",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"hypothesis>=6.0",
"coverage[toml]>=7.0",
"ruff>=0.6.0",
"pytest>=8.0",
"hypothesis>=6.0",
"coverage[toml]>=7.0",
"ruff>=0.6.0",
"build>=0.9",
"twine>=4.0",
]
[project.scripts]
jyotish = "jyotish_vedic.cli:main"
jyotish-engine = "jyotish_vedic.engine:cli_main"
jyotish-mcp = "jyotish_vedic.mcp_server:main"
[project.urls]
Homepage = "https://github.com/732642856/yinduzhanxing"
Documentation = "https://github.com/732642856/yinduzhanxing#readme"
Repository = "https://github.com/732642856/yinduzhanxing"
"Bug Reports" = "https://github.com/732642856/yinduzhanxing/issues"
Changelog = "https://github.com/732642856/yinduzhanxing/blob/main/CHANGELOG.md"
[tool.setuptools.packages.find]
where = ["."]
include = ["jyotish_vedic*"]
exclude = ["tests*", "docs*", "jyotish-app*", "benchmark*", "references*"]
[tool.setuptools.package-data]
jyotish_vedic = ["*.json", "*.md", "*.csv", "*.db"]
[tool.pytest.ini_options]
minversion = "8.0"
testpaths = ["tests"]
pythonpath = ["scripts"]
pythonpath = ["jyotish_vedic"]
addopts = "-q --strict-markers --strict-config"
markers = [
"slow: long-running validation tests",
"external: tests that depend on optional external datasets or tools",
"slow: long-running validation tests",
"external: tests that depend on optional external datasets or tools",
]
[tool.coverage.run]
branch = true
source = ["scripts"]
source = ["jyotish_vedic"]
omit = [
"scripts/add_high_confidence_yogas_batch1.py",
"scripts/build_standard_test_charts.py",
"scripts/_compute_one_chart.py",
"jyotish_vedic/add_high_confidence_yogas_batch1.py",
"jyotish_vedic/build_standard_test_charts.py",
"jyotish_vedic/_compute_one_chart.py",
]
[tool.coverage.report]
@@ -42,22 +87,22 @@ skip_covered = true
target-version = "py311"
line-length = 140
exclude = [
".git",
"__pycache__",
".pytest_cache",
"jyotish-app",
"benchmark",
".git",
"__pycache__",
".pytest_cache",
"jyotish-app",
"benchmark",
]
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]
ignore = [
"E501",
"E701",
"E702",
"E741",
"E501",
"E701",
"E702",
"E741",
]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S101"]
"scripts/validate_bphs_invariants.py" = ["T201"]
"jyotish_vedic/validate_bphs_invariants.py" = ["T201"]