Closes#14
Five globals (MIN_PA_VL, MIN_PA_VR, MIN_TBF_VL, MIN_TBF_VR, CARDSET_ID)
were derived from PLAYER_DESCRIPTION at module load time, creating a
hidden ordering dependency: any value baked in before the CLI overrides
PLAYER_DESCRIPTION would be silently wrong if a caller relied on the
derived relationship. The CLI explicitly sets all of them anyway, so
replacing with scalar defaults makes the module self-contained and safe.
Also collapses LAST_WEEK_RATIO dead ternary (both branches were 0.0).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#13
Replace `from db_calls_card_creation import *` with an explicit
`from db_calls_card_creation import PitcherData`. Only PitcherData
is referenced in creation_helpers.py; the wildcard was also
pulling in all Peewee ORM internals via a transitive
`from peewee import *`, polluting the namespace.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces logger.error() with logger.exception() so the full stack trace
is captured when a pitcher card fails to generate, making it possible to
diagnose the root cause rather than just seeing the error message.
Closes#17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#19
The conditional `0.0 if PLAYER_DESCRIPTION == 'Live' else 0.0` is dead
code: both branches evaluate to the same value. Simplified to a direct
assignment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#16
Deleted test_positions_df which called an async function synchronously
(returning a coroutine, not a DataFrame) and asserted True == True.
Zero coverage. Also removed the now-unused pd_positions_df import.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch hitters batting vs LHP hit right-handed (pull=lf, oppo=rf).
Switch hitters batting vs RHP hit left-handed (pull=rf, oppo=lf).
Copy-paste error had both pull_side branches returning the same value.
Closes#5
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The second `elif "DO*" in data_string` was dead code — the first always
matched, so `spaces -= 2` for the DO** variant was silently skipped.
Fix: check "DO**" first (spaces -= 2), then "DO*" (spaces -= 1).
Closes#6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#7
The fallback branch of create_pit_position() used `int(df_data["key_bbref"])`
which always raises ValueError for string IDs like 'verlaju01'. The exception
was silently swallowed, causing pitchers without defensive stats to receive no
position record at all.
Fix: use `int(float(df_data["player_id"]))` to match the pattern used in
create_pitching_card() on the same file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#10
Replace `except Exception: pass` with `except KeyError: pass` so only
the expected missing-attribute case (`cell["data-append-csv"]` not
present) is silently skipped. Network errors, encoding issues, and
other unexpected exceptions will now propagate instead of being hidden.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#24
Pins the two unpinned dependencies in requirements.txt:
- peewee (unversioned → 3.19.0)
- polars (unversioned → 1.36.1)
All other dependencies were already pinned with ==.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#15
`any` (lowercase) refers to the builtin function, not `typing.Any`.
Added `Any` to the `typing` imports in both files and updated the
`cardset` parameter annotation accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace hardcoded PD API bearer token in db_calls.py with dotenv/env var
- Delete scripts/supabase_doodling.py (dead scratch file with hardcoded Supabase JWT)
- Add python-dotenv dependency and .env.example template
- Consolidate check_prod_missing_ratings.py to import AUTH_TOKEN from db_calls
- Hard fail if PD_API_TOKEN is missing to prevent silent auth failures
Fixes#2, Fixes#3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow upload scripts to target a local API server instead of the remote
production server, enabling 32x+ concurrency for dramatically faster
full-cardset uploads (~30-45s vs ~2-3min for 800 cards).
- pd_cards/core/upload.py: add api_url param to upload_cards_to_s3(),
refresh_card_images(), and check_card_images()
- pd_cards/commands/upload.py: add --api-url CLI option to upload s3
- check_cards_and_upload.py: read PD_API_URL env var with prod fallback
- Update CLAUDE.md, CLI reference, and Phase 0 project plan docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
get_event_loop() is deprecated in Python 3.10+ when called inside
a running coroutine. get_running_loop() is the correct replacement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>