Skip to main content

Astrology calculations library — traditional Hellenistic focus, Swiss Ephemeris backed

Project description

astrologica

PyPI version Python versions License: MIT

A Python astrology library. Traditional Hellenistic focus, Swiss Ephemeris backed, domain-pure core.

Install

pip install astrologica              # core
pip install 'astrologica[geo]'       # + city lookup, timezone, elevation helpers

Quickstart

from datetime import datetime
from zoneinfo import ZoneInfo
from astrologica import ChartData, Place, Planet, compute_natal_chart

data = ChartData(
    datetime=datetime(1990, 5, 15, 14, 30, tzinfo=ZoneInfo("America/New_York")),
    place=Place(latitude=40.7128, longitude=-74.0060),
)

chart = compute_natal_chart(data)

sun = chart.planets[Planet.SUN]
print(sun.sign)                # Sign.TAURUS
print(sun.degree_in_sign)      # 24.72
print(sun.is_retrograde)       # False
print(sun.dignities)           # frozenset() — Sun has no essential dignity here
print(sun.house)               # 9
print(sun.solar_state)         # SolarState.FREE
print(sun.orientality)         # Orientality.NEUTRAL (Sun & Moon are NEUTRAL)
print(sun.face_ruler)          # Planet.SATURN  (third decan of Taurus)
print(sun.term_ruler)          # Planet.SATURN  (Egyptian: 27–30° Taurus)
print(sun.triplicity_rulers)   # TriplicityRulers(day=VENUS, night=MOON, participating=MARS)
print(sun.monomoira_ruler)     # Planet.SATURN  (per-degree ruler at 25° Taurus)
print(chart.is_diurnal)        # True
print(chart.almuten_figuris.winner)  # Planet.VENUS — chart's overall ruler

Don't know the timezone? Use the [geo] extra.

from astrologica import ChartTradition, Planet
from astrologica.geo import build_horary_chart, build_natal_chart

natal = build_natal_chart("1990-05-15T14:30", "New York")
modern = build_natal_chart("1990-05-15T14:30", "New York",
                           tradition=ChartTradition.MODERN)

horary = build_horary_chart("2025-06-01T12:00", "London", question_house=7)
print(horary.significator_of_querent, horary.significator_of_quesited)
print("Moon VOC:", horary.moon_is_void_of_course)

What's in the box

Every feature is a top-level import from astrologica. The natal Chart already contains planet positions, houses, aspects, lots, and the prenatal syzygy — the cookbook below shows everything else you can layer on.

Time-lord techniques. Five complementary systems for activating the chart over time: compute_zodiacal_releasing (Valens, releasing from Spirit or Fortune), compute_firdaria (Persian fixed-period, two nocturnal traditions), compute_decennials (Valens 126-year Mu cycle), compute_term_distribution (Naibod-directed Ascendant through term boundaries), and compute_annual_profection (Ptolemaic 12-house cycle). Pair any of them with compute_almuten_figuris for the chart's overall ruler, or compute_saturn_return and compute_secondary_progressions for life-stage markers.

Aspects

Computed automatically inside every Chart. To recompute standalone:

from astrologica import compute_aspects
aspects = compute_aspects(chart.planets)
for a in aspects:
    print(a.first, a.kind, a.second, f"orb={a.orb:.2f}°",
          "applying" if a.applying else "separating")

Transits — snapshot and range search

from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from astrologica import AspectKind, Planet, compute_transits, find_transits

now = datetime.now(ZoneInfo("UTC"))
snapshot = compute_transits(chart, now)
for ta in snapshot:
    print(f"t.{ta.transiting.name} {ta.kind.name} n.{ta.natal.name} orb={ta.orb:.2f}")

events = find_transits(
    chart,
    start=now,
    end=now + timedelta(days=365),
    transiting_bodies=[Planet.SATURN, Planet.JUPITER],
    natal_bodies=[Planet.SUN, Planet.MOON],
    aspects=[AspectKind.CONJUNCTION, AspectKind.OPPOSITION],
)

Returns (solar / lunar)

from datetime import datetime
from zoneinfo import ZoneInfo
from astrologica import compute_lunar_return, compute_solar_return

sr = compute_solar_return(chart, year=2026)              # birthday chart
lr = compute_lunar_return(chart, after=datetime.now(ZoneInfo("UTC")))

Pass place=Place(...) to either for a relocated return.

Secondary progressions

from astrologica import compute_secondary_progressions
progressed = compute_secondary_progressions(chart, age_years=35.5)

Primary directions (Placidian / Ptolemaic)

from astrologica import (
    ArcKey, DirectionApproach, DirectionType,
    compute_primary_directions,
)

directions = compute_primary_directions(
    chart,
    key=ArcKey.NAIBOD,                     # arc-to-years conversion
    direction=DirectionType.DIRECT,        # or CONVERSE
    approach=DirectionApproach.ZODIACAL,   # or MUNDANE
)
for d in directions:
    print(f"{d.promissor.name}{d.significator.name} {d.kind.name} "
          f"in {d.years:+.2f} years")

Zodiacal releasing

from astrologica import Lot, compute_zodiacal_releasing

periods = compute_zodiacal_releasing(
    chart,
    lot=Lot.SPIRIT,         # or Lot.FORTUNE
    max_level=4,            # 1 = major, 4 = sub-sub-sub
    year_length_days=360.0, # Valens' Egyptian year
)
for p in periods:
    marker = " LB" if p.is_lb else (" *peak*" if p.is_peak else "")
    print(f"L{p.level} {p.sign.name} {p.start.date()}{p.end.date()}{marker}")

Essential dignities

from astrologica import TermsSystem, compute_dignities

sun = chart.planets[Planet.SUN]
print(sun.dignities)   # set on every PlanetPosition

# Or compute standalone at any longitude:
d = compute_dignities(
    Planet.JUPITER, longitude=5.0,
    is_diurnal=True,
    terms_system=TermsSystem.EGYPTIAN,  # or PTOLEMAIC / CHALDEAN / …
)

Each PlanetPosition also exposes the rulers of the segment it falls in — handy without an extra lookup:

sun.face_ruler          # Chaldean-decan ruler (10° segment)
sun.term_ruler          # Egyptian term ruler (call term_of() for other systems)
sun.triplicity_rulers   # TriplicityRulers(day, night, participating)
sun.monomoira_ruler     # per-degree ruler at this longitude

# Sect-aware triplicity ruler:
tri_ruler = sun.triplicity_rulers.day if chart.is_diurnal else sun.triplicity_rulers.night

These describe the zodiacal segment, not the body — the face ruler at 0° Aries is Mars whether the position is occupied by the Sun, Saturn, or a node. They are also surfaced in Chart.to_dict() for serialisation.

Numeric dignity score (Lilly weights)

from astrologica import LILLY_WEIGHTS, Planet, dignity_score

# Mars at 0° Aries: domicile (+5) + face (+1) = 6.
score = dignity_score(Planet.MARS, 0.0, is_diurnal=True, weights=LILLY_WEIGHTS)

Pass your own EssentialWeights(domicile=..., exaltation=..., ...) to use a different scheme.

Almuten Figuris

from astrologica import compute_almuten_figuris

result = compute_almuten_figuris(chart)
print(result.winner)            # the winning planet, or None on dead heat
print(result.runners_up)        # tied/close runners after tie-break trace
print(result.totals)            # full per-planet score breakdown
for b in result.breakdown:
    print(b.point.label, b.per_planet)

The result also exposes split scoring — essential_totals (dignity points), accidental_totals (house-quality weights), and modifier_totals (state bonuses/penalties) — plus tie_break_trace explaining how the winner was selected. For an arbitrary point set, use compute_almuten(chart, points=[AlmutenPoint("MyLot", lon)], ...).

Custom weights and modifiers. Pass essential_weights, accidental_weights, or modifiers to override defaults:

from astrologica import (
    AlmutenModifiers, EssentialWeights, HouseQuality,
    compute_almuten_figuris,
)

result = compute_almuten_figuris(
    chart,
    essential_weights=EssentialWeights(
        domicile=5, exaltation=4, triplicity=3, term=2, face=1,
    ),
    accidental_weights={
        HouseQuality.ANGULAR: 4,
        HouseQuality.SUCCEDENT: 2,
        HouseQuality.CADENT: 0,
    },
    modifiers=AlmutenModifiers(
        combust=-5, under_beams=-4, cazimi=+5, retrograde=-5,
        aversion_to_asc=-2, oriental_bonus_superior=+2,
        occidental_bonus_inferior=+2, fast_or_direct_bonus=+1,
        angular_house=+5, succedent_house=+3, cadent_house=+0,
        malefic_in_6_or_12=-4,
    ),
)

Firdaria

from astrologica import FirdariaTradition, compute_firdaria

periods = compute_firdaria(chart, tradition=FirdariaTradition.AL_BIRUNI)
for p in periods:
    print(f"{p.ruler.name}: ages {p.start_age:.1f}{p.end_age:.1f}")
    for s in p.sub_periods:
        print(f"  {s.ruler.name}: {s.start_age:.2f}{s.end_age:.2f}")

Each major period is split into seven sub-periods (1/7 of the major span) cycling through the remaining six planets plus the major ruler itself. Node periods (TRUE_NODE, SOUTH_TRUE_NODE) have no sub-periods. The nocturnal sequence differs by tradition — AL_BIRUNI places the nodes at the end (most common); BONATTI places them mid-sequence after Mars. The diurnal sequence is identical in both.

Decennials (Valens)

from astrologica import compute_decennials

# Diurnal: Sun → Venus → Mercury → Moon → Saturn → Jupiter → Mars (Chaldean order from sect light)
# Nocturnal: Moon → Saturn → Jupiter → Mars → Sun → Venus → Mercury
# Total cycle: 126 years (the "Mu" cycle).
for p in compute_decennials(chart, max_age_years=82.0):
    print(f"{p.ruler.name}: ages {p.start_age}{p.end_age}")

Annual profection (Ptolemaic 12-house cycle)

from astrologica import compute_annual_profection

p = compute_annual_profection(chart, age_years=29)
print(p.profected_house, p.profected_sign.name, p.lord_of_year.name)
# year 0 → 1st house; the cycle repeats every 12 years.

Term distribution (Naibod-directed Ascendant)

from astrologica import compute_term_distribution

# Walk the Ascendant forward through term boundaries at the Naibod rate
# (≈0.986°/year). Each period's ruler is the Lord of that age-span.
for p in compute_term_distribution(chart, max_age_years=82.0):
    print(f"{p.ruler.name} ({p.sign.name}): ages {p.start_age:.1f}{p.end_age:.1f}")

Saturn return

from astrologica import compute_saturn_return

first  = compute_saturn_return(chart, n=1)   # ≈ age 29.5
second = compute_saturn_return(chart, n=2)   # ≈ age 59

Monomoira (per-degree ruler)

Each integer degree of the zodiac has a planetary ruler — the monomoira — taken from a 360-row table. Useful as fine-grain dignity data and as a tie-break in Almuten computations.

from astrologica import MONOMOIRAI, monomoira_of

ruler = monomoira_of(0.0)        # → Planet.MARS (0° Aries)
ruler = monomoira_of(24.72)      # ruler of the 25th degree of Aries
# MONOMOIRAI is the full 360-tuple if you want to walk the table directly.

Faces (decans), terms (bounds), triplicities

from astrologica import (
    FACES, TRIPLICITY_BY_ELEMENT, face_of, term_boundaries, triplicity_of,
)
from astrologica.terms import TERMS_EGYPTIAN, TermsSystem

Solar state, orientality, house quality, aversion

from astrologica import (
    Angle, Planet, SOLAR_STATE_THRESHOLDS, SolarStateThresholds,
    planet_solar_state, planet_orientality,
    house_quality, is_in_aversion_to,
)

state = planet_solar_state(chart.planets[Planet.VENUS], chart.planets[Planet.SUN])
# → SolarState.CAZIMI / COMBUST / UNDER_BEAMS / FREE
ori   = planet_orientality(Planet.JUPITER, chart.planets)
# → Orientality.ORIENTAL / OCCIDENTAL (or None for luminaries)
hq    = house_quality(7)              # → HouseQuality.ANGULAR
av    = is_in_aversion_to(Planet.MARS, Angle.ASCENDANT, chart)

# Override thresholds (defaults: cazimi 17', combust 8.5°, under-beams 17°)
state = planet_solar_state(
    chart.planets[Planet.VENUS], chart.planets[Planet.SUN],
    thresholds=SolarStateThresholds(
        cazimi_arcminutes=17.0, combust_degrees=8.5, under_beams_degrees=17.0,
    ),
)

Aspects to angles

from astrologica import Angle, compute_aspects

aspects = compute_aspects(
    chart.planets,
    include_angles=(Angle.ASCENDANT, Angle.MIDHEAVEN),
    chart=chart,
)

Optional nodes for traditional charts

chart = compute_natal_chart(data, include_nodes=True)
# now chart.planets contains TRUE_NODE and SOUTH_TRUE_NODE

Lots (Hellenistic) — classical seven + custom DSL

from astrologica import Lot
print(chart.lots[Lot.FORTUNE].sign, chart.lots[Lot.FORTUNE].degree_in_sign)

Build your own parts:

from astrologica import (
    CustomLot, LotFormula, Planet,
    CardinalAngle, CardinalAngleName, HouseCuspRef,
    LordOf, LordKind, RulerOf, RulerOfKind, PriorLot, SyzygyPoint,
    compute_custom_lot,
)

# Lot of Fortune, rebuilt:
fortune = CustomLot(
    name="Fortune",
    day=LotFormula(plus=(Planet.MOON,), minus=(Planet.SUN,)),
    night=LotFormula(plus=(Planet.SUN,), minus=(Planet.MOON,)),
)
# ASC is implicit in every formula; sect inversion is automatic.
longitude = compute_custom_lot(chart, fortune)

Formulas accept any LotComponent: bare Planet, CardinalAngle (e.g. MC), HouseCuspRef, LordOf (house lord), RulerOf (sign ruler of a body), PriorLot, or SyzygyPoint.

Fixed stars (30 classical)

from astrologica import FixedStar, compute_fixed_star_conjunctions

for conj in compute_fixed_star_conjunctions(chart, orb=1.0):
    print(f"{conj.body.name} conj {conj.star.name} (orb {conj.orb:.2f}°)")

Midpoints

from astrologica import compute_midpoints
mps = compute_midpoints(chart)  # 21 classical planet-pair midpoints

Antiscia / contraantiscia

from astrologica import compute_antiscion, compute_contraantiscion
compute_antiscion(15.0)         # solstitial-axis reflection
compute_contraantiscion(15.0)   # equinoctial-axis reflection

Dodecatemorion (twelfth-part)

from astrologica import DodecatemorionVariant, compute_dodecatemorion
compute_dodecatemorion(24.72)                                # Valens (default)
compute_dodecatemorion(24.72, DodecatemorionVariant.FIRMICUS)

Planetary hours (Chaldean order)

from datetime import date
from astrologica import Place, compute_planetary_hours

hours = compute_planetary_hours(
    on=date(2025, 6, 1),
    place=Place(latitude=51.5074, longitude=-0.1278),
)
for h in hours:
    print(h.ruler.name, h.start, "→", h.end, "day" if h.is_daytime else "night")

Rise / set / MC / IC

from datetime import date
from astrologica import Planet, Place, compute_rise_set

times = compute_rise_set(Planet.SUN, date(2025, 6, 1),
                         Place(latitude=51.5074, longitude=-0.1278))
print(times.rise, times.mc, times.set, times.ic)  # any may be None

Sign rising times at a latitude

from astrologica import Sign, compute_rising_times

rt = compute_rising_times(latitude_deg=40.7128)
for sign in Sign:
    print(sign.name, f"{rt[sign]:6.2f}°")  # sums to 360°

Prenatal syzygy

Already attached to every chart — no extra call needed:

print(chart.syzygy.kind.name, chart.syzygy.when, chart.syzygy.sign.name)
# → "NEW_MOON" or "FULL_MOON", the datetime, and the sign

Also callable directly against any moment if you need it standalone:

from astrologica import SwissEphemerisAdapter, compute_prenatal_syzygy
s = compute_prenatal_syzygy(chart.data.datetime, SwissEphemerisAdapter())

find_time — solve for a longitude crossing

from datetime import datetime
from zoneinfo import ZoneInfo
from astrologica import Planet, find_time

t = find_time(
    body=Planet.MARS,
    target_longitude=0.0,            # ingress into Aries
    start=datetime(2026, 1, 1, tzinfo=ZoneInfo("UTC")),
    end=datetime(2027, 1, 1, tzinfo=ZoneInfo("UTC")),
)

Horary

from astrologica import ChartData, Place, compute_horary_chart
data = ChartData.from_iso("2025-06-01T14:30:00+01:00",
                          Place(latitude=51.5074, longitude=-0.1278))
hc = compute_horary_chart(data, question_house=7)
print(hc.significator_of_querent, hc.significator_of_quesited,
      "VOC" if hc.moon_is_void_of_course else "")

Configuration

Every computation respects the ChartData and optional house system.

House systems

from astrologica import HouseSystem, compute_natal_chart
chart = compute_natal_chart(data, house_system=HouseSystem.PLACIDUS)
# Available: WHOLE_SIGN (default), PORPHYRY, ALCABITUS, REGIOMONTANUS, PLACIDUS

Sidereal zodiac (21 ayanamsas)

from astrologica import Ayanamsa, ChartData
data_sidereal = ChartData(datetime=..., place=..., ayanamsa=Ayanamsa.LAHIRI)

Available: FAGAN_BRADLEY, LAHIRI, DELUCE, RAMAN, USHASHASHI, KRISHNAMURTI, DJWHAL_KHUL, YUKTESHWAR, JN_BHASIN, BABYL_KUGLER1/2/3, BABYL_HUBER, BABYL_ETPSC, ALDEBARAN_15TAU, HIPPARCHOS, SASSANIAN, GALCENT_0SAG, J2000, J1900, B1950.

Reference frame

from astrologica import ChartData, ReferenceFrame
data_topo = ChartData(datetime=..., place=..., frame=ReferenceFrame.TOPOCENTRIC)
# Frames: GEOCENTRIC (default), TOPOCENTRIC, HELIOCENTRIC

Tradition (body set)

from astrologica import ChartTradition
compute_natal_chart(data, tradition=ChartTradition.MODERN)
# TRADITIONAL: 7 classical. MODERN: + Uranus, Neptune, Pluto + lunar nodes.

Terms systems

Threaded through the chart via ChartConfig.terms_system (see below): EGYPTIAN (default), PTOLEMAIC, CHALDEAN, DOROTHEAN, ASTROLOGICAL_ASSOCIATION. The chosen system drives every dignity-aware computation in the chart — per-planet dignities, term_ruler, and almuten_figuris.

ChartConfig — editorial knobs

compute_natal_chart accepts a config: ChartConfig kwarg bundling every editorial choice the chart makes. All defaults are Hellenistic-traditional, so you can ignore it; override sub-configs to suit your scheme.

from astrologica import (
    AlmutenConfig, AlmutenModifiers, ChartConfig, HouseQuality,
    TermsSystem, compute_natal_chart,
)

chart = compute_natal_chart(
    data,
    config=ChartConfig(
        terms_system=TermsSystem.PTOLEMAIC,
        almuten=AlmutenConfig(
            accidental_weights={
                HouseQuality.ANGULAR: 5,
                HouseQuality.SUCCEDENT: 3,
                HouseQuality.CADENT: 0,
            },
            modifiers=AlmutenModifiers(
                combust=-5, cazimi=+5, retrograde=-5,
                angular_house=+5, oriental_bonus_superior=+2,
            ),
            sect_aware=True,
        ),
    ),
)
chart.almuten_figuris.winner    # eagerly computed using the config
chart.config.terms_system       # echoed back for traceability

Adding new sub-configs (aspect orbs, solar-state thresholds, rulership scheme) is purely additive — existing call sites won't break.

Ephemeris data

No download required. The Swiss adapter uses the built-in Moshier analytical ephemeris for planet positions (accurate to a few arcseconds from 3000 BC to 3000 AD), and ships a minimal sefstars.txt inside the wheel so fixed-star lookups work out of the box.

If you want the higher-precision .se1 planet data, download the files from https://www.astro.com/ftp/swisseph/ephe/ (typically sepl_18.se1 + semo_18.se1 covers 1800–2399 AD) and point the adapter at them:

from astrologica import SwissEphemerisAdapter, compute_natal_chart
adapter = SwissEphemerisAdapter(ephe_path="/path/to/sweph/ephe")
chart = compute_natal_chart(data, ephemeris=adapter)

The same adapter can be reused across every compute_* call.

Serialization

import json
json.dumps(chart.to_dict(), indent=2)
# {
#   "datetime": "1990-05-15T14:30:00-04:00",
#   "utc": "1990-05-15T18:30:00+00:00",
#   "jd": 2448027.270833,
#   "place": {"latitude": 40.7128, "longitude": -74.006},
#   "house_system": "WHOLE_SIGN",
#   "tradition": "TRADITIONAL",
#   "ascendant": 171.12,
#   "midheaven": 81.04,
#   "is_diurnal": true,
#   "syzygy": {"kind": "FULL_MOON", ...},
#   "planets": {"SUN": {"sign": "TAURUS", "degree_in_sign": 24.72, ...}, ...},
#   "houses": [...], "aspects": [...], "lots": {...}
# }

The Chart aggregate

Field Type What it is
data ChartData the originating input (datetime, place, ayanamsa, frame)
config ChartConfig editorial knobs (terms system, almuten weights)
house_system HouseSystem the system used for cusps
tradition ChartTradition TRADITIONAL or MODERN body set
ascendant, midheaven Longitude angles
is_diurnal bool sect — Sun above horizon?
syzygy Syzygy prenatal lunation (kind / when / longitude / sign)
planets Mapping[Planet, PlanetPosition] per-body: position, speed, dignities, house, solar state, orientality, ruler properties
houses tuple[HouseCusp, ...] cusp longitudes
aspects tuple[Aspect, ...] Ptolemaic + semisextile + quincunx, including aspects to Asc/MC
lots Mapping[Lot, LotPosition] classical seven lots
almuten_figuris AlmutenResult chart's overall ruler, eagerly computed from config.almuten

Architecture

Port-adapter / hexagonal. The domain layer is pyswisseph-free; Swiss Ephemeris lives behind an EphemerisPort. Public API at astrologica.*; internals under astrologica._internal.* (enforced by import-linter contracts). Frozen, slots-using dataclasses throughout; every chart is JSON-serialisable via Chart.to_dict(). Type-hint friendly — the package ships a py.typed marker.

Custom backends (e.g. for tests) are a drop-in:

from astrologica import EphemerisPort, compute_natal_chart
class MyEphemeris(EphemerisPort): ...
compute_natal_chart(data, ephemeris=MyEphemeris())

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

astrologica-0.2.0.tar.gz (171.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

astrologica-0.2.0-py3-none-any.whl (148.8 kB view details)

Uploaded Python 3

File details

Details for the file astrologica-0.2.0.tar.gz.

File metadata

  • Download URL: astrologica-0.2.0.tar.gz
  • Upload date:
  • Size: 171.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for astrologica-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dd222e1cbd4e9b3f9cfc34e004f3c0b0b98926a74c22470eb9ac171a631cd0d4
MD5 a5b60e0b5bb944552a07a56fffb0ffea
BLAKE2b-256 09cf01299d5204259b0e760b44ba98c9a4a331a5a359fee0ee98bd6d755687b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for astrologica-0.2.0.tar.gz:

Publisher: publish.yml on milanpredic/astrologica

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file astrologica-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: astrologica-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 148.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for astrologica-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 89f3be8970547705729a351f0897ccfa34eaa8a09593e5cc6c598e280a9f80d2
MD5 243a3cf278a0e7f3571c8a8a7c5d6305
BLAKE2b-256 b0ff6d3e208091313a5da8fcfa834a45a17dcc090ce8a692e85ca244ae2580b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for astrologica-0.2.0-py3-none-any.whl:

Publisher: publish.yml on milanpredic/astrologica

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page