Repository navigation
Add FXMacroData tool to the Atomic Forge - #297
roberttidball wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Historical review of 79f02c32.
The macro history/calendar tool has useful distinct coverage, and your affiliation and free/paid split are disclosed. I reproduced four issues offline at 79f02c32 using actual Requests/Pydantic and dummy keys:
- Credential forwarding,
tool/fxmacrodata.py:174: a 302 from the HTTPS API to an unrelated HTTP host carriesX-API-Keyto that host. Keep authenticated requests on the intended HTTPS origin. - Secret in returned errors, lines106/173/190: a key with leading whitespace triggers
InvalidHeader, and stringifying that exception returns the complete key. Error messages must exclude credential values. - Malformed responses, lines192-200: HTTP200 with
{detail: 'upstream failure'}or invaliddatavalues becomeserror=None, data=[]. Other malformed bodies raise outputValidationErroroutside the advertised error-return contract. Validate the response shape and return a useful error. - Date inputs, lines142-148: impossible dates and reversed ranges reach the request; an empty start date silently disappears. Use real date validation and range checks.
The author suite passes: 23 tests. The independent failure probes still reproduce these cases. Canonical Black127 and repository Flake8 also pass, so import spacing isn't a blocker.
On this historical head, native production complexity was CC14 for build_request and CC8 for run. The earlier score-only refactor request is withdrawn.
Please remove the UTM referral parameters from the README links, including the subscription link, and use neutral service URLs. No live API calls, real credentials or purchases were used in this review.
The later offline review of 184709f3 confirms redirect/header/error/date repairs and neutral links. At 0ed527b4, 63 author tests and 132 independent observations also confirm pagination, config masking and ordinary nested-response redaction repairs. The findings above describe the historical head; the current review instead identifies redaction collisions/validation bypass and malformed-port error handling.
38a76fd to
184709f
Compare
|
Thanks for the careful review and the reproductions. All four are fixed in 184709f:
Also from your notes: request building and response parsing are split into small functions (radon max CC is now 5, |
There was a problem hiding this comment.
Historical review of 184709f3.
Rechecked 184709f3. The redirect, unsafe-header, returned-error and date repairs pass the offline probes. Twenty redirect variants send only the intended HTTPS request, invalid dates send zero requests, and the referral parameters are gone. All 24 production functions now have genuine measured CRAP scores below 6.
Two remaining blockers in tool/fxmacrodata.py:
- Malformed pagination, lines209-212: HTTP200
{data: [], pagination: []}still returnserror=None, pagination=None.false,0and an empty string also pass. Validate a present pagination value beforeor {}normalizes it. - Credential exposure, lines114-117 and278-282: the complete dummy key appears in the actual config repr/str. A successful response with
{data: [], detail: 'echo ' + key}also copies it into metadata and output repr. Hide credentials in config representations and protect successful output paths as well as error strings.
A lower-priority configuration concern: malformed HTTPS base URLs such as https:// raise InvalidURL/ValueError outside the advertised error-return path, before any request. Validate config early or make that exception contract explicit.
The author suite passes all 44 tests. Seventy-seven independent offline Requests/Pydantic observations verify the repairs and reproduce the remaining cases. Black127 and canonical Flake8 pass. Keep the useful assertions. No live API, real credentials, vendor installation or purchases were used.
The later offline review of 0ed527b4 confirms pagination validation, config masking and ordinary nested-response redaction repairs. It still reproduces redaction collisions/validation bypass and the malformed-port error path. The 44-test result and 77 observations above belong to 184709f3.
c0f1e61 to
0ed527b
Compare
|
Thanks for rechecking. All three are addressed in 0ed527b:
63 tests pass with 100% line coverage, every function is at or below complexity 5, and Black (127) and Flake8 are clean. |
There was a problem hiding this comment.
Rechecked 0ed527b4 offline: all 63 author tests pass, and 132 independent Requests/Pydantic observations confirm the pagination, config masking and ordinary nested-response redaction repairs. All 27 production functions have genuine measured native CRAP scores below 6.
Two remaining findings in tool/fxmacrodata.py:
- Redaction loses data and bypasses validation, lines278-279 and313: a successful row with two keys that sanitize to
[redacted]silently loses one value. Catalogue, metadata and pagination collisions reproduce too. With the dummy keytotal_count,pagination.total_count=Trueis renamed before validation and returnserror=None. Validate the original structure first and preserve colliding values when sanitizing output. - Malformed port escapes the error-output path, lines140-143 and312:
https://api.fxmacrodata.com:bad/v1passes config validation, thenrunraisesRequests.InvalidURLbefore any send. Validate the port at config creation or handle that failure consistently.
Production coverage is 167/167 statements and 32/32 measured branches, with 13 unchanged main-example exclusions. Current-head style was not verified; keep the useful assertions. No live API, real credentials, vendor installation or source changes.
I run FXMacroData, the macro data API this tool calls.
Summary
Adds
atomic-forge/tools/fxmacrodata, a Forge tool for official-source macroeconomic data: release history for an indicator with the official announcement timestamp of each print (CPI, GDP, unemployment, payrolls, policy rates, yields), the latest value of every indicator for a currency, upcoming release dates, the indicator catalogue, FX spot history, CFTC COT positioning, and commodity prices.One tool covers these through an
endpointliteral in the input schema, the same wayfia_signalsselects its sub-tool, withcurrency,indicator,quote,start_date,end_date,limitandoffsetalongside it. The output keeps the API's own row fields indata, puts paging info inpagination, and keeps the rest of the top-level response (source, units, provenance) inmetadata, so nothing is dropped or renamed.USD data, the USD release calendar and the catalogue work without a key, so the tool runs out of the box. Other currencies, FX, COT and commodities need a key, read from
FXMacroDataToolConfig.api_keyor theFXMACRODATA_API_KEYenvironment variable and sent asX-API-Key. Likeweather, the tool reports problems in anerrorfield instead of raising, because the common failure (asking for EUR data without a key) comes back with a message the agent can act on.Changes
atomic-forge/tools/fxmacrodata/tool/fxmacrodata.py: the tool (requests, syncrunplusrun_asyncviaasyncio.to_thread)atomic-forge/tools/fxmacrodata/tests/test_fxmacrodata.py: 23 unit tests (request path and query for every endpoint, input validation before any request is made, row/pagination/metadata split, catalogue mapping, key from config and from env, key never in the returned URL, HTTP errors with and without a JSON body, network errors, async)README.md,pyproject.toml,requirements.txt,.coveragerc: same shape as the other toolsatomic-forge/README.md,AGENTS.md,docs/guides/tools.md,README.md: one listing line each, after Fía Signalsuv.lock: the new workspace member only (additive)Verification
flake8(repo.flake8) clean on the new directory;black --checkwith the repo's line length passes apart from the blank line after imports, which follows the existing toolspytest atomic-forge/tools/fxmacrodata/tests: 23 passeduv lock --checkpasseserror