# Quick Start ## Authentication `Grad300Client` (aliased as `Grad300`) accepts either a **username + password** pair or a pre-obtained **Bearer token**. ```python from grad300_client import Grad300 # Authenticate with username / password (token acquired automatically) client = Grad300(user="student@example.com", password="your-password") # — or — supply a token directly client = Grad300(token="eyJhb...") ``` You can also use it as a **context manager** so the underlying HTTP connection is closed automatically: ```python with Grad300(user="student@example.com", password="your-password") as client: table = client.query_source("Sun") ``` --- ## Querying scans All query methods return an [`astropy.table.Table`](https://docs.astropy.org/en/stable/table/) whose columns mirror the {py:class}`~grad300_client.ScanRecord` fields (`id`, `scan_type`, `file_name`, `source`, `ra`, `dec`, `date`, …). ### By source name ```python # All scan types for "Sun" table = client.query_source("Sun") # Only TPI scans tpi_table = client.query_source("Sun", scan_type="TPI") print(tpi_table["file_name", "date"]) ``` ### By partial filename ```python # Matches any scan whose file_name contains "2025062" table = client.query_scan_name("2025062") ``` ### By date range ```python from datetime import datetime march_scans = client.query_date_range( date_from=datetime(2026, 3, 1), date_to=datetime(2026, 3, 31, 23, 59, 59), ) ``` ### Combined filters ```python table = client.query( scan_type="TPI", source="Jupiter", date_from=datetime(2026, 1, 1), max_results=50, ) ``` --- ## Downloading scans The {py:meth}`~grad300_client.Grad300Client.download` family of methods returns different types depending on the scan type: | Scan type | In-memory return type | |-----------|----------------------| | `TPI` | {py:class}`astropy.table.Table` | | `Images`, `Spectrum`, `OnOff` | {py:class}`astropy.io.fits.HDUList` | ### In-memory download ```python # From a table row obtained via a query row = table[0] data = client.download(row) # TPI → astropy Table if hasattr(data, "colnames"): print(data["Azimuth", "Elevation"]) # Other → HDUList else: data.info() ``` ### Download to disk ```python from pathlib import Path path = client.download(row, destination_dir=Path("./downloads")) print(f"Saved to {path}") ``` ### Download by scan ID or filename ```python # By ID (must provide scan_type explicitly) data = client.download_by_id(scan_type="TPI", scan_id=42) # By exact filename (searches first, then downloads) path = client.download_by_scan_name( "MyScan_2026.fits", destination_dir="./downloads", ) ``` --- ## Working with results as records If you prefer Python objects instead of an astropy Table, use the `*_records` variants: ```python records = client.query_records(source="Sun", scan_type="TPI") for r in records: print(r.file_name, r.date, r.ra, r.dec) ``` Each item is a {py:class}`~grad300_client.ScanRecord` dataclass.