Add public_user_profile to Crypto API (resolve model_id by name)#1
Add public_user_profile to Crypto API (resolve model_id by name)#1lingster wants to merge 1 commit into
Conversation
CryptoAPI had no way to resolve a model name (the "username" shown on the crypto leaderboard) to a model_id, which is required by submission_scores, diagnostics, staking, etc. public_user_profile existed only on the Classic and Signals APIs. The v3UserProfile GraphQL field accepts a `tournament` argument that disambiguates a model name within a given tournament. The previous Classic and Signals implementations ignored it, so a name shared across tournaments could resolve to the wrong model's id (verified: "quixotic15" returns a different id with vs without tournament=12). This unifies all three into a single base_api.Api.public_user_profile that passes `tournament=self.tournament_id`, so: - CryptoAPI gains public_user_profile (tournament 12) - Signals/Classic resolve names within their own tournament (11 / 8) - the duplicated overrides in numerapi.py and signalsapi.py are removed (DRY) Verified end-to-end against the live API and the Numerai MCP: a fresh crypto leaderboard name resolves to its model_id and that id drives submission_scores. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25bca132e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| data = self.raw_query(query, arguments)["data"]["v3UserProfile"] | ||
| # convert strings to python objects | ||
| utils.replace(data, "startDate", utils.parse_datetime_string) | ||
| utils.replace(data, "nmrStaked", utils.parse_float_string) |
There was a problem hiding this comment.
Preserve Classic nmrStaked return type
For NumerAPI.public_user_profile callers, this new shared conversion changes nmrStaked from the raw GraphQL string returned by the previous Classic implementation into a Decimal. That is a public API/serialization change unrelated to adding Crypto support; for example existing Classic users doing json.dumps(api.public_user_profile(...)) or string-based persistence/comparisons can now fail or behave differently. Keep the conversion scoped to APIs that already returned Decimal, or make the Classic behavior an explicit compatibility break.
Useful? React with 👍 / 👎.
|
Superseded by upstream PR numerai#128. |
Problem
submission_scores(anddiagnostics, staking, etc.) require amodel_id,but the Crypto API had no way to resolve a model name → model_id.
public_user_profileexisted only onNumerAPI(Classic) andSignalsAPI,so there was no supported path to map the usernames shown on the crypto
leaderboard to the UUIDs the rest of the API expects.
Fix
The
v3UserProfileGraphQL field accepts atournamentargument thatdisambiguates a model name within a tournament. The old Classic/Signals
implementations ignored it — meaning a name shared across tournaments could
resolve to the wrong model's id (verified:
quixotic15returns adifferent id with vs. without
tournament=12).This unifies all three tournaments into a single
base_api.Api.public_user_profilethat passestournament=self.tournament_id:CryptoAPIgainspublic_user_profile(tournament 12) — the missing piecenumerapi.pyandsignalsapi.pyremoved (DRY)Return shape is unchanged (
id,username,startDate,bio,nmrStaked).Usage
Testing (red/green TDD)
test_cryptoapi.pyandtest_signalsapi.pyassert the modelis resolved within the API's own tournament and that string fields are
converted. Written failing first, then made to pass.
45 passed(live-API tests deselected).pyflakesclean.Independently verified against the live API + Numerai MCP
v3_user_profile(no tournament) for a crypto modelnull(reproduces the bug)v3UserProfile(tournament: 12)2d844064-...CryptoAPI().public_user_profile(...)['id']2d844064-...(matches)submission_scores(model_id)🤖 Generated with Claude Code