To use this application (igardner/StockAnalysis: Structured stock analysis as JSON for agents): API schema: GET https://igardner-stockanalysis.hf.space/gradio_api/info Call endpoint: POST https://igardner-stockanalysis.hf.space/gradio_api/call/v2/analyze {"ticker": "AAPL", "horizon": "3 months", "risk_profile": "balanced", "question": ""} Poll result: GET https://igardner-stockanalysis.hf.space/gradio_api/call/analyze/{event_id} File inputs: none - all inputs are JSON scalars. Auth: Bearer $HF_TOKEN (https://huggingface.co/settings/tokens) # StockAnalysis agent contract This file is the concrete contract for agents. The Hub also generates a live `agents.md` at `https://huggingface.co/spaces/igardner/StockAnalysis/agents.md`. Always fetch `/gradio_api/info` before calling. The live schema is the runtime contract; this file explains the boundaries and the expected response shapes. ## What this Space does - Accepts a ticker, horizon, risk profile, and optional question. - Sends that request to a separate stock-analysis project. - Returns three outputs in order: JSON, the raw upstream body, and a short human-readable status string. - If the upstream returns text and a local parser is configured, converts that text to JSON without inventing prices, targets, or recommendations. The Analyze request is read-only. It does not place trades, move funds, or connect to a brokerage account. ## Boundaries: what this Space will not do - It is not financial advice and is not a substitute for a licensed advisor. - It does not guarantee returns, accuracy, completeness, availability, or latency. Do not represent it as promising 10x gains or any other return. - It does not execute trades or manage money. - It does not verify the external project's claims or data. - It does not provide personalized advice. Treat output as research material that a human reviews. - It does not accept file inputs. Do not call `/gradio_api/upload`. - It does not expose the smoke test as part of the agent contract. The smoke test events are marked private; do not call them. - It does not promise uptime. This is a CPU-basic Space and can sleep, restart, or be rebuilt. - It does not intentionally persist Analyze requests. The external project may have its own retention policy. ## Promises: what agents can rely on - When the Gradio call completes, it returns exactly three outputs in this order: JSON result, raw upstream body, status string. - The first output is JSON-serializable. Error and configuration failures are returned as JSON objects instead of a successful-looking analysis. - Expected failures use these `status` values: `not_configured`, `invalid_input`, or `error`. A text-to-JSON wrapper uses `status: "ok"` plus `source: "external+local_parser"`. - An upstream JSON response is passed through unchanged. Its shape is defined by the external project, not by this Space. - Missing or empty tickers return `invalid_input`. Unknown horizon or risk values are coerced to `3 months` and `balanced`. - The Space never returns `HF_TOKEN` or any server secret in its outputs. - Private smoke-test outputs are not part of the Analyze response. ## Inputs | Name | Type | Required | Default | Rules | |---|---|---|---|---| | `ticker` | string | yes | none | Uppercased and trimmed. Maximum 24 characters. Empty is rejected. | | `horizon` | string | no | `3 months` | `1 week`, `1 month`, `3 months`, `6 months`, or `1 year`. Unknown values become `3 months`. | | `risk_profile` | string | no | `balanced` | `conservative`, `balanced`, or `aggressive`. Unknown values become `balanced`. | | `question` | string | no | empty | Optional. Truncated to 2000 characters. Do not put secrets or personal data here. | There are no file inputs. ## Outputs 1. JSON result. Read this first. 2. Raw upstream response as text. May be empty. 3. Human-readable status string. Do not parse this as machine data. The JSON result can be one of these shapes: - Upstream JSON, passed through unchanged. - `{"status": "ok", "ticker": "...", "http_status": 200, "content_type": "...", "raw": "..."}` when the upstream returned text and no parser was configured. - `{"status": "ok", "ticker": "...", "source": "external+local_parser", "parser": {"model": "..."}, "analysis": , "raw": "..."}` when the local parser succeeded. - `{"status": "not_configured", "message": "..."}` when `EXTERNAL_API_URL` is unset. - `{"status": "invalid_input", "error": "..."}` for bad input. - `{"status": "error", "http_status": ..., "error": "...", "raw": "..."}` for upstream failures. - The text-wrapper shape plus `parse_error` when the local parser failed. Check for the `status` field before treating a result as analysis. Our error envelopes include `ticker` and an `error` or `message` field. Upstream JSON is not wrapped, so its own fields are whatever the external project returns. ## Call with curl ```bash EVENT_ID=$(curl -sS -X POST \ "https://igardner-stockanalysis.hf.space/gradio_api/call/v2/analyze" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $HF_TOKEN" \ -d '{"ticker":"AAPL","horizon":"3 months","risk_profile":"balanced","question":""}' \ | python -c 'import json,sys; print(json.load(sys.stdin)["event_id"])') curl -sS -N \ "https://igardner-stockanalysis.hf.space/gradio_api/call/analyze/$EVENT_ID" \ -H "Authorization: Bearer $HF_TOKEN" ``` The POST returns `{"event_id": "..."}`. The GET streams Server-Sent Events. The final event is `complete` and its `data` field is the three-element output list. An `error` event means the call failed; a stream that ends without `complete` should be treated as a failure. If a client only supports the older call shape, send the same inputs as a positional list to `/gradio_api/call/analyze`: ```json {"data": ["AAPL", "3 months", "balanced", ""]} ``` ## Call with the Python client ```python import os from gradio_client import Client client = Client("igardner/StockAnalysis", token=os.environ["HF_TOKEN"]) result = client.predict( "AAPL", "3 months", "balanced", "", api_name="/analyze", ) print(result) ``` ## Error handling and retries - Check the JSON result's `status` before using any analysis fields. - Do not retry `invalid_input` or `not_configured`. Fix the input or ask the Space owner to set `EXTERNAL_API_URL`. - For HTTP 429, 5xx, network errors, or a stream without `complete`, retry with exponential backoff and a small retry cap (for example, three attempts). Honor `Retry-After` when it is present. - Do not retry a `parse_error` blindly. The raw upstream body is still in the second output, so use that if your client can parse it. - The server allows up to four concurrent Analyze events. Stay below that, and do not flood the Space with parallel requests. ## Auth and data handling - Send `Authorization: Bearer $HF_TOKEN` on both the POST and the poll GET. - Never put the token in the JSON body, the `question` field, or a URL query string. - `HF_TOKEN` is for Space authentication and rate limits. The Space's own outbound token is a Space secret and is never returned to clients. - The ticker and question are sent to the external project. Do not send secrets, credentials, or personal data. - The Space does not intentionally store Analyze requests. The external project may log or retain them under its own policy. ## Discovery and versioning - Fetch `GET /gradio_api/info` at the start of a session. Do not hardcode parameter names, return counts, or endpoint paths beyond the documented fallback. - The live `/agents.md` route is generated by Hugging Face from Space metadata. This repository copy is documentation, not a replacement for the live schema. - The external project and the custom model can change independently. The custom model is configured with `STOCK_MODEL_ID` and is currently blank. ## Disclaimer This is research tooling, not financial advice. Output may be incomplete or wrong. No return is guaranteed, and you can lose money. Nothing in this contract promises a specific gain, including 10x.