<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: massimo minganti</title>
    <description>The latest articles on DEV Community by massimo minganti (@mmi24).</description>
    <link>https://dev.to/mmi24</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4002618%2F05327eda-a299-441f-b2b4-fdc4ec5954dd.png</url>
      <title>DEV Community: massimo minganti</title>
      <link>https://dev.to/mmi24</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mmi24"/>
    <language>en</language>
    <item>
      <title>How I built a free astrology synastry calculator with Python and Swiss Ephemeris</title>
      <dc:creator>massimo minganti</dc:creator>
      <pubDate>Thu, 25 Jun 2026 15:28:19 +0000</pubDate>
      <link>https://dev.to/mmi24/how-i-built-a-free-astrology-synastry-calculator-with-python-and-swiss-ephemeris-41gp</link>
      <guid>https://dev.to/mmi24/how-i-built-a-free-astrology-synastry-calculator-with-python-and-swiss-ephemeris-41gp</guid>
      <description>&lt;p&gt;When my partner asked me to check our astrological compatibility, I did what any developer would do: I built the tool myself instead of using the existing ones.&lt;/p&gt;

&lt;p&gt;The result is Coppiastrale — a free synastry and natal chart calculator for couples, built with Python and real ephemeris data. Here's what I learned.&lt;/p&gt;

&lt;p&gt;What is synastry?&lt;br&gt;
Synastry is the astrological technique of comparing two birth charts to assess compatibility. You overlay two natal charts and analyze the geometric angles (aspects) formed between one person's planets and the other's — conjunctions, oppositions, trines, squares, and so on.&lt;/p&gt;

&lt;p&gt;The stack&lt;br&gt;
Flask (SSR, not a SPA — SEO was a core requirement)&lt;br&gt;
Kerykeion — a Python library wrapping pyswisseph (Swiss Ephemeris)&lt;br&gt;
GeoNames API — birth place → lat/lng + IANA timezone&lt;br&gt;
svgwrite — for rendering the chart wheels&lt;br&gt;
SQLite + SQLAlchemy — only for the paid flow, the free calculator stores zero PII&lt;br&gt;
The key constraint: the free tool had to be completely stateless. No user accounts, no stored birth data, no cookies beyond a slim session reference.&lt;/p&gt;

&lt;p&gt;The hardest part: timezone handling&lt;br&gt;
Swiss Ephemeris needs UTC. Users give you a city name and a local time. The tricky bit is converting correctly — especially for historical dates where DST rules were different.&lt;/p&gt;

&lt;p&gt;GeoNames returns real IANA timezone identifiers (e.g. Europe/Rome), which you then pass to pytz or zoneinfo. I initially used a simpler geocoder that returned UTC offsets directly — this caused wrong chart calculations for births before 1970 in several countries. Switching to IANA + zoneinfo fixed it.&lt;/p&gt;

&lt;p&gt;from zoneinfo import ZoneInfo&lt;br&gt;
from datetime import datetime&lt;/p&gt;

&lt;p&gt;def to_utc(date_str, time_str, iana_tz):&lt;br&gt;
    local_dt = datetime.strptime(f"{date_str} {time_str}", "%Y-%m-%d %H:%M")&lt;br&gt;
    local_dt = local_dt.replace(tzinfo=ZoneInfo(iana_tz))&lt;br&gt;
    return local_dt.astimezone(ZoneInfo("UTC"))&lt;br&gt;
Synastry scoring&lt;br&gt;
Each inter-aspect gets a base score from a YAML config file (conjunction with Venus = high, square with Saturn = low, etc.). I then apply a sigmoid normalization to compress everything into a 0–100 scale that feels intuitive to non-astrologers.&lt;/p&gt;

&lt;p&gt;The weights live in a versioned YAML file — not in the DB — so I can tweak the astrological logic without a schema migration.&lt;/p&gt;

&lt;p&gt;SVG chart rendering&lt;br&gt;
Kerykeion can generate SVG wheels natively, but I needed a custom dual-wheel layout for synastry (inner wheel = person A, outer wheel = person B, lines between related planets). I ended up using svgwrite to draw the overlay programmatically on top of Kerykeion's base geometry.&lt;/p&gt;

&lt;p&gt;The trickiest part: placing planet glyphs at the right angle without overlapping when two planets are within 3° of each other. I added a collision-detection pass that nudges labels radially outward.&lt;/p&gt;

&lt;p&gt;SEO as the product moat&lt;br&gt;
The free calculator is the SEO lure. The app generates ~365 indexable pages: 78 canonical sign-pair compatibility pages, 72 planet-in-sign pages, 12 sign profiles, 144 Sun×Ascendant combinations — all with structured data (BreadcrumbList, Article, FAQPage schemas).&lt;/p&gt;

&lt;p&gt;Since it's Flask SSR, all of this is crawlable without JavaScript rendering.&lt;/p&gt;

&lt;p&gt;What I'd do differently&lt;br&gt;
Don't use Flask sessions for large payloads. Cookies max out at 4KB. I store the full chart JSON in localStorage and only keep a slim reference in the session. Learned this the hard way after charts started silently truncating.&lt;/p&gt;

&lt;p&gt;Test timezone edge cases early. Write a test for a birth in Indiana before 2006 (they didn't observe DST). If that passes, you're probably fine.&lt;/p&gt;

&lt;p&gt;Try it - and let me know your comments!&lt;/p&gt;

&lt;p&gt;The calculator is live at coppiastrale.it (Italian interface, but the math works for anyone). Happy to answer questions about the ephemeris stack or the scoring algorithm.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>webdev</category>
      <category>flask</category>
    </item>
    <item>
      <title>Hello !</title>
      <dc:creator>massimo minganti</dc:creator>
      <pubDate>Thu, 25 Jun 2026 15:25:01 +0000</pubDate>
      <link>https://dev.to/mmi24/hello--1h7n</link>
      <guid>https://dev.to/mmi24/hello--1h7n</guid>
      <description>&lt;p&gt;Hello everyone!&lt;br&gt;
I am new so this is my new post&lt;/p&gt;

&lt;p&gt;I used to be a programmer but this was 20 years ago - now I have started again as I would like to work on my projects when - quite soon - I will be in retirement&lt;/p&gt;

&lt;p&gt;I am starting with a project about astrology - then ...who knows!&lt;/p&gt;

&lt;p&gt;Hope to have fun, to learn, to communicate and find some buds!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>sideprojects</category>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
