diff --git a/swifttools/swift_too/swift/calendar.py b/swifttools/swift_too/swift/calendar.py index 992f141..41cff09 100755 --- a/swifttools/swift_too/swift/calendar.py +++ b/swifttools/swift_too/swift/calendar.py @@ -1,6 +1,6 @@ from datetime import datetime -from pydantic import BaseModel, Field +from pydantic import BaseModel from ..base.common import TOOAPIBaseclass from ..base.repr import TOOAPIReprMixin @@ -22,8 +22,12 @@ class SwiftCalendarGetSchema(BaseModel): dec: AstropyAngle | None = None too_id: int | None = None radius: AstropyAngle | None = 12 / 60.0 + target_id: int | None = None targetid: int | None = None - status: TOOStatus = Field(default_factory=TOOStatus) + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None class SwiftCalendarEntry(BaseSchema, TOOAPIClockCorrect, TOOAPIReprMixin): @@ -122,7 +126,12 @@ class SwiftCalendarSchema(BaseSchema, TOOAPIReprMixin): ra: AstropyAngle | None = None dec: AstropyAngle | None = None radius: AstropyAngle | None = None + target_id: int | None = None targetid: int | None = None + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None entries: list[SwiftCalendarEntry] = [] status: TOOStatus = TOOStatus() diff --git a/swifttools/swift_too/swift/guano.py b/swifttools/swift_too/swift/guano.py index cdab292..e45fdd7 100644 --- a/swifttools/swift_too/swift/guano.py +++ b/swifttools/swift_too/swift/guano.py @@ -197,7 +197,11 @@ class SwiftGUANOGetSchema(OptionalBeginEndLengthSchema): triggertime: datetime | None = None limit: int | None = None page: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None triggertype: str | None = None + queue: int | None = None model_config = ConfigDict(extra="ignore") @@ -209,7 +213,6 @@ def validate_parameters(cls, values): return if not isinstance(values, dict): values = values.__dict__ - print(values) for key in cls.model_fields.keys(): if key in values: good = True @@ -221,10 +224,14 @@ def validate_parameters(cls, values): class SwiftGUANOSchema(BaseSchema): begin: datetime | None = None end: datetime | None = None + username: str = Field(default="anonymous") subthreshold: bool = False successful: bool = True triggertime: datetime | None = None limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None triggertype: str | None = None lastcommand: datetime | None = None guanostatus: bool | None = None diff --git a/swifttools/swift_too/swift/obsquery.py b/swifttools/swift_too/swift/obsquery.py index a0733be..e5e50d1 100644 --- a/swifttools/swift_too/swift/obsquery.py +++ b/swifttools/swift_too/swift/obsquery.py @@ -150,6 +150,11 @@ class SwiftAFSTGetSchema(BaseModel): radius: AstropyAngle | None = None target_id: int | list[int] | None = None obs_id: ObsIDSDC | list[ObsIDSDC] | None = None + gw_event: str | None = None + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None model_config = ConfigDict(extra="ignore") @@ -172,6 +177,11 @@ class SwiftAFSTSchema(OptionalCoordinateSchema, OptionalBeginEndLengthSchema): radius: AstropyAngle | None = None target_id: int | list[int] | None = None obs_id: ObsIDSDC | list[ObsIDSDC] | None = None + gw_event: str | None = None + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None afstmax: datetime | SwiftDateTimeSchema | None = None entries: list[SwiftAFSTEntry] = [] status: TOOStatus = TOOStatus() diff --git a/swifttools/swift_too/swift/planquery.py b/swifttools/swift_too/swift/planquery.py index ac29c35..34fdd78 100644 --- a/swifttools/swift_too/swift/planquery.py +++ b/swifttools/swift_too/swift/planquery.py @@ -18,6 +18,10 @@ class SwiftPPSTGetSchema(OptionalBeginEndLengthSchema, OptionalCoordinateSchema) radius: AstropyAngle | None = None target_id: int | list[int] | None = None obs_id: ObsIDSDC | list[ObsIDSDC] | None = None + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None model_config = ConfigDict(extra="ignore") @@ -122,6 +126,10 @@ class SwiftPPSTSchema(OptionalBeginEndLengthSchema, OptionalCoordinateSchema): radius: AstropyAngle | None = None target_id: int | list[int] | None = None obs_id: ObsIDSDC | list[ObsIDSDC] | None = None + limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None ppstmax: datetime | None = None entries: list[SwiftPPSTEntry] = Field(default_factory=list) status: TOOStatus = Field(default_factory=TOOStatus) diff --git a/swifttools/swift_too/swift/requests.py b/swifttools/swift_too/swift/requests.py index 844a037..d206b4a 100644 --- a/swifttools/swift_too/swift/requests.py +++ b/swifttools/swift_too/swift/requests.py @@ -11,7 +11,11 @@ class SwiftTOORequestsGetSchema(OptionalBeginEndLengthSchema, OptionalCoordinateSchema): + username: str | None = None limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None page: int | None = None year: int | None = None detail: bool = False @@ -28,6 +32,7 @@ def validate_at_least_one_param(cls, data): if isinstance(data, dict): # Exclude model_config and other class attributes params = [ + "username", "begin", "end", "length", @@ -48,6 +53,9 @@ class SwiftTOORequestsSchema(BaseSchema): begin: datetime | None = None length: float | None = None limit: int | None = None + offset: int | None = None + sort_by: str | None = None + order: str | None = None year: int | None = None detail: bool = False too_id: int | None = None diff --git a/swifttools/swift_too/swift/uvot.py b/swifttools/swift_too/swift/uvot.py index 540e743..b59f1b4 100644 --- a/swifttools/swift_too/swift/uvot.py +++ b/swifttools/swift_too/swift/uvot.py @@ -50,7 +50,7 @@ class SwiftUVOTModeEntry(BaseSchema, TOOAPIReprMixin): comment on special modes """ - uvot_mode: int = 0 + uvot_mode: int filter_num: int | None = None min_exposure: int | None = None filter_pos: int | None = None @@ -62,7 +62,7 @@ class SwiftUVOTModeEntry(BaseSchema, TOOAPIReprMixin): weight: int | None = None special: int | None = None comment: str | None = None - filter_name: str | None = None + filter_name: str class SwiftUVOTModeSchema(BaseSchema): @@ -99,7 +99,7 @@ class SwiftUVOTMode(TOOAPIBaseclass, TOOAPIInstruments, SwiftUVOTModeSchema, TOO def _post_process(self): if len(self.entries) == 0: - self.entries = [SwiftUVOTModeEntry(uvot_mode=self.uvot_mode or 0)] + self.entries = [SwiftUVOTModeEntry(uvot_mode=self.uvot_mode or 0, filter_name="")] def __getitem__(self, index): return self.entries[index] diff --git a/tests/swift_too/base/common/test_constants.py b/tests/swift_too/base/common/test_constants.py new file mode 100644 index 0000000..27e6fa2 --- /dev/null +++ b/tests/swift_too/base/common/test_constants.py @@ -0,0 +1,12 @@ +import importlib + + +def test_default_swift_too_api_url(monkeypatch): + monkeypatch.delenv("SWIFT_TOO_API_URL", raising=False) + + import swifttools.swift_too.base.constants as constants + + reloaded = importlib.reload(constants) + expected = f"https://www.swift.psu.edu/api/v{reloaded.API_VERSION}" + + assert reloaded.API_URL == expected diff --git a/tests/swift_too/swift/schemas/test_schemas.py b/tests/swift_too/swift/schemas/test_schemas.py new file mode 100644 index 0000000..14a6190 --- /dev/null +++ b/tests/swift_too/swift/schemas/test_schemas.py @@ -0,0 +1,45 @@ +from datetime import datetime, timedelta + +from swifttools.swift_too.swift.schemas import SwiftObservationSchema + + +class TestSwiftObservationSchema: + def test_settle_field_is_declared(self): + schema = SwiftObservationSchema( + begin=datetime(2023, 1, 1, 12, 0, 0), + settle=datetime(2023, 1, 1, 12, 1, 0), + end=datetime(2023, 1, 1, 12, 10, 0), + ) + + assert schema.settle == datetime(2023, 1, 1, 12, 1, 0) + + def test_time_properties_are_none_safe(self): + schema = SwiftObservationSchema( + begin=datetime(2023, 1, 1, 12, 0, 0), + end=datetime(2023, 1, 1, 12, 10, 0), + ) + + assert schema.exposure is None + assert schema.slewtime is None + + def test_table_uses_none_when_deltas_unavailable(self): + schema = SwiftObservationSchema( + begin=datetime(2023, 1, 1, 12, 0, 0), + end=datetime(2023, 1, 1, 12, 10, 0), + target_name="Test Target", + obs_id="00012345001", + ) + + _, data = schema._table + assert data[0][4] is None + assert data[0][5] is None + + def test_time_properties_when_complete(self): + schema = SwiftObservationSchema( + begin=datetime(2023, 1, 1, 12, 0, 0), + settle=datetime(2023, 1, 1, 12, 1, 0), + end=datetime(2023, 1, 1, 12, 10, 0), + ) + + assert schema.exposure == timedelta(minutes=9) + assert schema.slewtime == timedelta(minutes=1) diff --git a/tests/swift_too/swift/uvot/conftest.py b/tests/swift_too/swift/uvot/conftest.py index 0fe401a..0da51a0 100644 --- a/tests/swift_too/swift/uvot/conftest.py +++ b/tests/swift_too/swift/uvot/conftest.py @@ -34,15 +34,15 @@ def uvot_mode_with_entries(uvot_mode_empty): @pytest.fixture def uvot_entry(): - return SwiftUVOTModeEntry(uvot_mode=0x30ED) + return SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name="") @pytest.fixture def sample_uvot_entries(): """List of sample SwiftUVOTModeEntry objects for testing.""" return [ - SwiftUVOTModeEntry(uvot_mode=0x30ED), - SwiftUVOTModeEntry(uvot_mode=0x30ED), + SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name=""), + SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name=""), ] @@ -57,9 +57,9 @@ def uvot_mode_with_two_entries(uvot_mode_empty, sample_uvot_entries): def uvot_mode_with_three_entries(uvot_mode_empty): """SwiftUVOTMode instance with three entries.""" entries = [ - SwiftUVOTModeEntry(uvot_mode=0x30ED), - SwiftUVOTModeEntry(uvot_mode=0x30ED), - SwiftUVOTModeEntry(uvot_mode=0x30ED), + SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name=""), + SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name=""), + SwiftUVOTModeEntry(uvot_mode=0x30ED, filter_name=""), ] uvot_mode_empty.entries = entries return uvot_mode_empty diff --git a/tests/swift_too/swift/uvot/test_uvot.py b/tests/swift_too/swift/uvot/test_uvot.py index 35b83bd..5d41e8a 100644 --- a/tests/swift_too/swift/uvot/test_uvot.py +++ b/tests/swift_too/swift/uvot/test_uvot.py @@ -44,7 +44,7 @@ def test_init_uvot_mode(self, uvot_entry): assert uvot_entry.uvot_mode == 0x30ED def test_init_filter_name(self, uvot_entry): - assert uvot_entry.filter_name is None + assert uvot_entry.filter_name == "" def test_init_eventmode(self, uvot_entry): assert uvot_entry.eventmode is None