Spaces:
Running
Running
Add Astroseek MCP integration to UI - new External Charts tab
Browse files
app.py
CHANGED
|
@@ -538,10 +538,15 @@ def create_demo():
|
|
| 538 |
- **Zodiacal Releasing** - Explore major life periods from Vettius Valens' system
|
| 539 |
|
| 540 |
### π Learn Traditional Astrology
|
| 541 |
-
- **
|
| 542 |
- **Source Research** - Educational content citing ancient texts
|
| 543 |
- **Study Resources** - Curated books, courses, and free learning materials
|
| 544 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
### ποΈ Built on Ancient Foundations
|
| 546 |
All techniques are drawn from authentic Hellenistic sources (1st-7th century CE),
|
| 547 |
not modern psychological astrology. We preserve the traditional methods exactly as
|
|
@@ -787,6 +792,235 @@ def create_demo():
|
|
| 787 |
5. Explore bounds, decans, and advanced timing
|
| 788 |
""")
|
| 789 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 790 |
with gr.Tab("βΉοΈ About"):
|
| 791 |
gr.Markdown("""
|
| 792 |
## About HERMES
|
|
|
|
| 538 |
- **Zodiacal Releasing** - Explore major life periods from Vettius Valens' system
|
| 539 |
|
| 540 |
### π Learn Traditional Astrology
|
| 541 |
+
- **Text-Based Teaching** - AI-powered explanations of Hellenistic techniques
|
| 542 |
- **Source Research** - Educational content citing ancient texts
|
| 543 |
- **Study Resources** - Curated books, courses, and free learning materials
|
| 544 |
|
| 545 |
+
### π External Integrations
|
| 546 |
+
- **Astroseek MCP** - Fetch chart data from external sources (proof-of-concept)
|
| 547 |
+
- **Modal Serverless** - 6 MCP functions deployed for calculations
|
| 548 |
+
- **Local Fallback** - All calculations available offline
|
| 549 |
+
|
| 550 |
### ποΈ Built on Ancient Foundations
|
| 551 |
All techniques are drawn from authentic Hellenistic sources (1st-7th century CE),
|
| 552 |
not modern psychological astrology. We preserve the traditional methods exactly as
|
|
|
|
| 792 |
5. Explore bounds, decans, and advanced timing
|
| 793 |
""")
|
| 794 |
|
| 795 |
+
with gr.Tab("π External Charts (Astroseek)"):
|
| 796 |
+
gr.Markdown("""
|
| 797 |
+
### Astroseek.com Chart Integration
|
| 798 |
+
|
| 799 |
+
Fetch chart data from external sources via MCP integration.
|
| 800 |
+
|
| 801 |
+
β οΈ **Note**: This is a proof-of-concept web scraping integration.
|
| 802 |
+
For production use, consider official APIs or local ephemeris calculations.
|
| 803 |
+
""")
|
| 804 |
+
|
| 805 |
+
with gr.Row():
|
| 806 |
+
with gr.Column():
|
| 807 |
+
gr.Markdown("#### Birth Data")
|
| 808 |
+
|
| 809 |
+
astro_date = gr.Textbox(
|
| 810 |
+
label="Birth Date (YYYY-MM-DD)",
|
| 811 |
+
placeholder="1990-01-15",
|
| 812 |
+
value="1990-01-15"
|
| 813 |
+
)
|
| 814 |
+
|
| 815 |
+
astro_time = gr.Textbox(
|
| 816 |
+
label="Birth Time (HH:MM)",
|
| 817 |
+
placeholder="12:00",
|
| 818 |
+
value="12:00"
|
| 819 |
+
)
|
| 820 |
+
|
| 821 |
+
astro_lat = gr.Number(
|
| 822 |
+
label="Latitude",
|
| 823 |
+
value=40.7128,
|
| 824 |
+
precision=4
|
| 825 |
+
)
|
| 826 |
+
|
| 827 |
+
astro_lon = gr.Number(
|
| 828 |
+
label="Longitude",
|
| 829 |
+
value=-74.0060,
|
| 830 |
+
precision=4
|
| 831 |
+
)
|
| 832 |
+
|
| 833 |
+
astro_chart_btn = gr.Button("π Fetch Chart from Astroseek", variant="primary")
|
| 834 |
+
|
| 835 |
+
with gr.Column():
|
| 836 |
+
gr.Markdown("#### Daily Horoscope")
|
| 837 |
+
|
| 838 |
+
astro_sign = gr.Dropdown(
|
| 839 |
+
choices=["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
|
| 840 |
+
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"],
|
| 841 |
+
label="Zodiac Sign",
|
| 842 |
+
value="Aries"
|
| 843 |
+
)
|
| 844 |
+
|
| 845 |
+
astro_horoscope_btn = gr.Button("π Get Daily Horoscope", variant="secondary")
|
| 846 |
+
|
| 847 |
+
astro_output = gr.Textbox(
|
| 848 |
+
label="Results",
|
| 849 |
+
lines=25,
|
| 850 |
+
max_lines=40,
|
| 851 |
+
show_copy_button=True
|
| 852 |
+
)
|
| 853 |
+
|
| 854 |
+
def fetch_astroseek_chart(date, time, lat, lon):
|
| 855 |
+
"""Fetch chart from Astroseek"""
|
| 856 |
+
try:
|
| 857 |
+
from astroseek_mcp import AstroseekMCP
|
| 858 |
+
|
| 859 |
+
client = AstroseekMCP()
|
| 860 |
+
result = client.calculate_chart(
|
| 861 |
+
birth_date=date,
|
| 862 |
+
birth_time=time,
|
| 863 |
+
latitude=float(lat),
|
| 864 |
+
longitude=float(lon)
|
| 865 |
+
)
|
| 866 |
+
|
| 867 |
+
if "error" in result:
|
| 868 |
+
return f"""## β Error Fetching Chart
|
| 869 |
+
|
| 870 |
+
**Error Message**: {result['error']}
|
| 871 |
+
|
| 872 |
+
**Note**: {result.get('note', 'Web scraping integration may require updates.')}
|
| 873 |
+
|
| 874 |
+
### Troubleshooting:
|
| 875 |
+
- Check internet connection
|
| 876 |
+
- Verify Astroseek.com is accessible
|
| 877 |
+
- This is a proof-of-concept integration
|
| 878 |
+
- Consider using local ephemeris (pyswisseph) instead
|
| 879 |
+
|
| 880 |
+
### Alternative:
|
| 881 |
+
Use the main HERMES calculators in other tabs for:
|
| 882 |
+
- Essential Dignities
|
| 883 |
+
- Lots (Fortune, Spirit)
|
| 884 |
+
- Annual Profections
|
| 885 |
+
- Zodiacal Releasing
|
| 886 |
+
- Bounds & Decans
|
| 887 |
+
"""
|
| 888 |
+
|
| 889 |
+
# Format the result
|
| 890 |
+
output = f"""## π Chart Data from Astroseek.com
|
| 891 |
+
|
| 892 |
+
**Birth Date**: {result.get('birth_date', 'N/A')}
|
| 893 |
+
**Birth Time**: {result.get('birth_time', 'N/A')}
|
| 894 |
+
**Location**: {result.get('location', {}).get('latitude', 'N/A')}, {result.get('location', {}).get('longitude', 'N/A')}
|
| 895 |
+
|
| 896 |
+
### Planet Positions:
|
| 897 |
+
"""
|
| 898 |
+
planets = result.get('planets', {})
|
| 899 |
+
if planets:
|
| 900 |
+
for planet, data in planets.items():
|
| 901 |
+
output += f"- **{planet}**: {data.get('position', 'N/A')}"
|
| 902 |
+
if data.get('retrograde'):
|
| 903 |
+
output += " β (Retrograde)"
|
| 904 |
+
output += "\n"
|
| 905 |
+
else:
|
| 906 |
+
output += "*No planet data available (HTML parsing may need update)*\n"
|
| 907 |
+
|
| 908 |
+
output += "\n### House Cusps:\n"
|
| 909 |
+
houses = result.get('houses', [])
|
| 910 |
+
if houses:
|
| 911 |
+
for house in houses:
|
| 912 |
+
output += f"- **House {house.get('house', '?')}**: {house.get('cusp', 'N/A')}\n"
|
| 913 |
+
else:
|
| 914 |
+
output += "*No house data available*\n"
|
| 915 |
+
|
| 916 |
+
output += "\n### Aspects:\n"
|
| 917 |
+
aspects = result.get('aspects', [])
|
| 918 |
+
if aspects:
|
| 919 |
+
for aspect in aspects[:10]: # Show first 10
|
| 920 |
+
output += f"- {aspect.get('planet1', '?')} {aspect.get('aspect', '?')} {aspect.get('planet2', '?')} (orb: {aspect.get('orb', '?')})\n"
|
| 921 |
+
else:
|
| 922 |
+
output += "*No aspect data available*\n"
|
| 923 |
+
|
| 924 |
+
output += f"\n---\n*Source: {result.get('source', 'astroseek.com')}*"
|
| 925 |
+
|
| 926 |
+
return output
|
| 927 |
+
|
| 928 |
+
except ImportError:
|
| 929 |
+
return """## β οΈ Astroseek Integration Not Available
|
| 930 |
+
|
| 931 |
+
The Astroseek MCP integration requires additional dependencies.
|
| 932 |
+
|
| 933 |
+
**To enable:**
|
| 934 |
+
1. Install: `pip install beautifulsoup4 lxml requests`
|
| 935 |
+
2. Restart the application
|
| 936 |
+
|
| 937 |
+
**Alternative**: Use HERMES built-in calculators in other tabs.
|
| 938 |
+
"""
|
| 939 |
+
except Exception as e:
|
| 940 |
+
return f"""## β Error
|
| 941 |
+
|
| 942 |
+
**Error Type**: {type(e).__name__}
|
| 943 |
+
**Message**: {str(e)}
|
| 944 |
+
|
| 945 |
+
This is a proof-of-concept web scraping integration.
|
| 946 |
+
For reliable chart data, use HERMES built-in calculators or official APIs.
|
| 947 |
+
"""
|
| 948 |
+
|
| 949 |
+
def fetch_daily_horoscope(sign):
|
| 950 |
+
"""Fetch daily horoscope from Astroseek"""
|
| 951 |
+
try:
|
| 952 |
+
from astroseek_mcp import AstroseekMCP
|
| 953 |
+
|
| 954 |
+
client = AstroseekMCP()
|
| 955 |
+
result = client.get_daily_horoscope(sign)
|
| 956 |
+
|
| 957 |
+
if "error" in result:
|
| 958 |
+
return f"""## β Error Fetching Horoscope
|
| 959 |
+
|
| 960 |
+
**Error**: {result['error']}
|
| 961 |
+
|
| 962 |
+
**Note**: Web scraping may require updates if Astroseek changed their HTML structure.
|
| 963 |
+
"""
|
| 964 |
+
|
| 965 |
+
return f"""## π Daily Horoscope for {sign}
|
| 966 |
+
|
| 967 |
+
**Date**: {result.get('date', 'Today')}
|
| 968 |
+
|
| 969 |
+
{result.get('horoscope', 'Horoscope text not available')}
|
| 970 |
+
|
| 971 |
+
---
|
| 972 |
+
*Source: {result.get('source', 'astroseek.com')}*
|
| 973 |
+
|
| 974 |
+
β οΈ **Disclaimer**: This is fetched from Astroseek.com for demonstration purposes.
|
| 975 |
+
Traditional Hellenistic astrology uses natal charts and time-lord techniques (see other tabs) rather than sun-sign horoscopes.
|
| 976 |
+
"""
|
| 977 |
+
|
| 978 |
+
except ImportError:
|
| 979 |
+
return "β οΈ Astroseek integration requires beautifulsoup4, lxml, and requests packages."
|
| 980 |
+
except Exception as e:
|
| 981 |
+
return f"β Error: {str(e)}"
|
| 982 |
+
|
| 983 |
+
astro_chart_btn.click(
|
| 984 |
+
fn=fetch_astroseek_chart,
|
| 985 |
+
inputs=[astro_date, astro_time, astro_lat, astro_lon],
|
| 986 |
+
outputs=astro_output
|
| 987 |
+
)
|
| 988 |
+
|
| 989 |
+
astro_horoscope_btn.click(
|
| 990 |
+
fn=fetch_daily_horoscope,
|
| 991 |
+
inputs=astro_sign,
|
| 992 |
+
outputs=astro_output
|
| 993 |
+
)
|
| 994 |
+
|
| 995 |
+
gr.Markdown("""
|
| 996 |
+
---
|
| 997 |
+
### π§ About This Integration
|
| 998 |
+
|
| 999 |
+
**What it does:**
|
| 1000 |
+
- Fetches chart data from Astroseek.com
|
| 1001 |
+
- Demonstrates MCP integration with external services
|
| 1002 |
+
- Shows how HERMES can connect to third-party APIs
|
| 1003 |
+
|
| 1004 |
+
**Limitations:**
|
| 1005 |
+
- Web scraping (not an official API)
|
| 1006 |
+
- Requires internet connection
|
| 1007 |
+
- May break if Astroseek changes HTML
|
| 1008 |
+
- Rate limited (1 request/second)
|
| 1009 |
+
- Subject to Astroseek's terms of service
|
| 1010 |
+
|
| 1011 |
+
**Better Alternatives:**
|
| 1012 |
+
- Use HERMES built-in calculators (other tabs)
|
| 1013 |
+
- Swiss Ephemeris via pyswisseph (included)
|
| 1014 |
+
- Astro.com API (official)
|
| 1015 |
+
- AstroDienst API
|
| 1016 |
+
|
| 1017 |
+
**Why include this?**
|
| 1018 |
+
This demonstrates HERMES can integrate with external chart services through the MCP protocol,
|
| 1019 |
+
showing architectural flexibility for the MCP Birthday Hackathon.
|
| 1020 |
+
|
| 1021 |
+
For actual chart analysis, use the HERMES calculators in the other tabs!
|
| 1022 |
+
""")
|
| 1023 |
+
|
| 1024 |
with gr.Tab("βΉοΈ About"):
|
| 1025 |
gr.Markdown("""
|
| 1026 |
## About HERMES
|