from planetarypy.constants import G, c, k_B, M_sun, R_earth
G\(6.6743 \times 10^{-11} \; \mathrm{\frac{m^{3}}{kg\,s^{2}}}\)
planetarypy.constants is a one-stop source for solar-system work, layering three reference sets in a single namespace:
G, c, h, k_B, M_sun, R_earth, …) — thin re-exports of astropy.constants so you don’t manage two imports. CODATA-versioned, authoritative.Per-body fields come back as a Constant (an astropy.units.Quantity subclass) carrying full provenance — which kernel or NSSDC capture supplied it. The default surface merges PCK and NSSDC transparently: PCK wins for cartographic fields when both have data; NSSDC fills in everything PCK doesn’t carry.
No separate astropy.constants import needed:
\(6.6743 \times 10^{-11} \; \mathrm{\frac{m^{3}}{kg\,s^{2}}}\)
Import a body, access its fields:
\(42828.374 \; \mathrm{\frac{km^{3}}{s^{2}}}\)
A Constant is an astropy.units.Quantity plus metadata. The source, reference, and description attributes identify the origin so a paper citing a particular Mars GM can always be traced back to the exact kernel or NSSDC capture used.
"IAU 2015 — Archinal et al., 'Report of the IAU Working Group on Cartographic Coordinates and Rotational Elements: 2015', Celest. Mech. Dyn. Astr. (2018)"
The registry exposes lookup by NAIF id and case-insensitive name, plus helpers grouped by physical class.
['MERCURY',
'VENUS',
'EARTH',
'MARS',
'JUPITER',
'SATURN',
'URANUS',
'NEPTUNE',
'PLUTO']
['MIMAS',
'ENCELADUS',
'TETHYS',
'DIONE',
'RHEA',
'TITAN',
'HYPERION',
'IAPETUS']
['BORRELLY',
'CHURYUMOV-GERASIMENKO',
'HALLEY',
'TEMPEL 1',
'WILD 2',
'CERES',
'VESTA',
'LUTETIA',
'MATHILDE',
'EROS',
'STEINS',
'ITOKAWA',
'BENNU']
Body.at_time(date) returns a snapshot using whichever PCK edition was current on that date — no need to know submodule names. IAU 2009 PCK was published 2010-10-21; IAU 2015 PCK was published 2018-09-20.
# Mars pole declination, as a 2012 paper would have seen it
mars_2012 = Mars.at_time('2012')
mars_2024 = Mars.at_time('2024')
print(f"2012 (IAU 2009): pole_dec = {mars_2012.pole_dec}")
print(f"2024 (IAU 2015): pole_dec = {mars_2024.pole_dec}")
print(f"Δ over edition jump: {mars_2024.pole_dec - mars_2012.pole_dec}")
print()
print(f"Sources:")
print(f" 2012: {mars_2012.pole_dec.source}")
print(f" 2024: {mars_2024.pole_dec.source}")2012 (IAU 2009): pole_dec = 52.8865 deg
2024 (IAU 2015): pole_dec = 54.432516 deg
Δ over edition jump: 1.5460160000000016 deg
Sources:
2012: pck00010.tpc
2024: pck00011.tpc
Body.at_time(date) returns a snapshot of the body with all fields resolved as of that date. It walks both the PCK editions and the NSSDC capture history per field, returning the most recent value that was current on or before the requested date.
date accepts "2001", "2001-06", or "2001-06-15". Year-only and year-month resolve to the end of that period, so “what was current in 2001” picks the latest 2001 capture rather than the first.
(<Constant Mars.bond_albedo = 0.16 (NSSDC marsfact.html updated 1998-11-27)>,
<Constant Mars.bond_albedo = 0.25 (NSSDC marsfact.html updated 2024-10-03)>)
\(0.16 \; \mathrm{}\)
2000: 22 satellites
2005: 47 satellites
2010: 62 satellites
2015: 62 satellites
2020: 82 satellites
2024: 146 satellites
PCK kernels have their own publication date — the IAU 2009 PCK was released 2010-10-21. For dates before that, at_time falls back to NSSDC even for fields PCK normally wins. So a query for “what was Mars’s GM in 2008?” returns NSSDC’s GM (the only published value at that date), while “what was Mars’s GM in 2024?” returns the PCK value.
The default Mars.GM returns the PCK value. If you specifically want NSSDC’s GM (which may differ slightly — different solutions), reach through the nssdc submodule. Same shape as the IAU-edition submodules.
(<Constant Jupiter.GM = 1.26687e+08 km3 / s2 (IAU 2015)>,
<Constant Jupiter.GM = 1.26687e+08 km3 / s2 (NSSDC jupiterfact.html updated 2024-10-02)>)
2000-11-13: 22
2002-10-15: 30
2004-09-01: 33
2010-08-09: 62
2014-04-25: 62
2015-12-22: 62
2016-02-29: 62
2016-05-19: 62
2016-12-23: 62
2018-09-27: 62
2021-12-16: 82
2024-10-03: 146
Pair nssdc.history() with matplotlib for a quick drift plot — here’s Saturn’s known moon count climbing from 18 to 274 across three decades:
import matplotlib.pyplot as plt
from datetime import date
hist = nssdc.history('saturn', 'number_of_satellites')
dates = [date.fromisoformat(d) for d, _, _ in hist]
counts = [int(v.value) for _, v, _ in hist]
fig, ax = plt.subplots(figsize=(8, 3.5))
ax.step(dates, counts, where='post', linewidth=2)
ax.set_ylabel('Known moons')
ax.set_title("Saturn's satellite count — NSSDC revisions, 1996–2025")
ax.grid(True, alpha=0.3)
fig.tight_layout()Text(0, 0.5, 'Known moons')
Text(0.5, 1.0, "Saturn's satellite count — NSSDC revisions, 1996–2025")

| Use case | Surface |
|---|---|
| Everyday “give me Mars’s mass” | from planetarypy.constants import Mars |
| “What was the value at the time?” (paper reproducibility) | Mars.at_time('2012').pole_dec |
| Drift / science-history study | nssdc.history(body, field) |
| Deliberately citing NSSDC over PCK | from planetarypy.constants.nssdc import Mars |
| Fundamental physics constants (G, c, M_sun, …) | from planetarypy.constants import G, c, M_sun |