Skip to content

qrz_logbook_status silently returns 0/empty for dxcc, start_date and end_date: STATUS field names don't match the API response #5

Description

@MicaelJarniac

Summary

qrz_logbook_status returns dxcc: 0, start_date: "" and end_date: "" for logbooks that clearly have those values. count, confirmed and callsign are correct, so the tool looks like it is working — the wrong fields fail silently rather than erroring.

Found while verifying the fix for #3 against a live logbook.

Root cause

LogbookClient.status() reads key names that the QRZ ACTION=STATUS response does not use.

Verbatim live response (key redacted, PU2UMK, 30 QSOs):

CONFIRMED=3&COUNT=30&CALLSIGN=PU2UMK&BOOK_NAME=PU2UMK Logbook&END_DATE=2044-07-25&START_DATE=2024-09-03&ACTION=STATUS&OWNER=PU2UMK&DXCC_COUNT=1&RESULT=OK&BOOKID=406135

src/qrz_mcp/logbook_client.py:179-187 reads:

return LogbookStatus(
    callsign=kv.get("OWNER", ""),
    count=_int("COUNT"),
    confirmed=_int("CONFIRMED"),
    dxcc=_int("DXCC"),           # response has DXCC_COUNT
    us_states=_int("US_STATES"), # see note below
    start_date=kv.get("START", ""),  # response has START_DATE
    end_date=kv.get("END", ""),      # response has END_DATE
)

_int() defaults to "0" on a missing key and kv.get(..., "") defaults to empty, so every mismatch degrades quietly instead of surfacing.

output field code reads in live response live value result
callsign OWNER yes PU2UMK ok
count COUNT yes 30 ok
confirmed CONFIRMED yes 3 ok
dxcc DXCC no (DXCC_COUNT) 1 0
start_date START no (START_DATE) 2024-09-03 ""
end_date END no (END_DATE) 2044-07-25 ""
us_states US_STATES not present 0 (unconfirmed, see below)

Response keys currently ignored: BOOKID, BOOK_NAME, CALLSIGN, DXCC_COUNT, END_DATE, START_DATE.

Reproduction

result = qrz_logbook_status(persona="...")
# {'callsign': 'PU2UMK', 'count': 30, 'confirmed': 3,
#  'dxcc': 0,          <- response says DXCC_COUNT=1
#  'us_states': 0,
#  'start_date': '',   <- response says START_DATE=2024-09-03
#  'end_date': ''}     <- response says END_DATE=2044-07-25

Why tests miss it

_MOCK_STATUS_BODY (logbook_client.py:110) encodes the expected names rather than the API's actual ones:

_MOCK_STATUS_BODY = "RESULT=OK&COUNT=1547&DXCC=142&US_STATES=48&CONFIRMED=892&OWNER=KI7MT&START=20180101&END=20260301"

Every one of DXCC, US_STATES, START, END exists in the mock and none exist on the wire, so QRZ-L2-036/037 pass while live calls return zeros. Same root pattern as #3: the fixture encodes what the code wants, not what QRZ sends.

Suggested fix

Read the documented names, ideally with a fallback so both spellings work:

def _first(*keys: str) -> str:
    for k in keys:
        if k in kv:
            return kv[k]
    return ""

dxcc=_int_of(_first("DXCC_COUNT", "DXCC")),
start_date=_first("START_DATE", "START"),
end_date=_first("END_DATE", "END"),
callsign=_first("OWNER", "CALLSIGN"),

and update _MOCK_STATUS_BODY to the real wire format so the fixture can catch this class of drift.

Two things worth deciding, since they are judgement calls rather than clear bugs:

  • us_states is unconfirmed. No US-states-like key appears in my response, but this logbook has worked 0 US states, so QRZ may simply omit zero-valued keys. I can't tell a rename from an omission with this data. Someone with a US logbook could settle it in one call — the answer changes whether this needs a rename or is already correct.
  • OWNER vs CALLSIGN. Both are present and identical here. They may diverge for shared or multi-operator books, so which one callsign should mean is a semantic choice for the maintainer.

Note

Distinct from #3 (HTML-escaped ADIF), which only affects fetch/download. status parses fine — it just looks up the wrong keys. Deliberately left out of #4 to keep that diff scoped. Happy to send a PR.


AI disclosure

This issue was written by an AI agent (Claude, via OpenCode) working from a human-directed prompt, and was found while verifying the fix for #3 against a live logbook using maintainer-supplied credentials.

All values quoted above were read from actual API responses, not inferred. Where the data could not settle a question — the us_states field — that is stated as unresolved rather than guessed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions