How breakhearts/jqcli works
1. What this repo is
- jqcli is a Python 3.9+ tool for automating JoinQuant workflows: authentication, strategy CRUD, formal backtests/compile runs, backtest inspection, and community post discovery.
- The repo is organized around one external boundary: the real JoinQuant web UI/API. Most features are wrappers over server-rendered pages and JSON endpoints rather than a public SDK.
2. Top-level architecture
- There are three major surfaces:
- a command-line interface for interactive and automation use,
- an HTTP/API client layer that speaks to JoinQuant,
- a web subapp for local management/archiving tasks.
- Shared concerns such as config loading, credential precedence, error codes, and output formatting are centralized so both CLI and web flows behave consistently.
3. CLI entrypoint and command routing
- jqcli/cli.py is the root entrypoint; jqcli/commands/* splits behavior by domain: auth, strategy, backtest, community, and web.
- This layer is thin: it parses arguments, enforces interactivity/confirmation rules, and delegates to API/service objects.
- The CLI is designed for machine consumption first: JSON output, non-interactive mode, and explicit exit codes are part of the contract.
4. Configuration and credential resolution
- jqcli/config.py handles environment-file loading, persistent local config, API base URL selection, timeout, and saved credential lookup.
- Credential precedence matters architecturally: command-line overrides environment variables, which override saved local config, with login able to persist cookies back to config.
- This is the main boundary between local state and remote access; all downstream API calls depend on a resolved auth context.
5. Core HTTP/API layer
- jqcli/api/client.py is the shared transport foundation, with domain modules in jqcli/api/auth.py, strategy.py, backtest.py, and community.py.
- These modules encapsulate JoinQuant-specific endpoints, request/response shaping, and parsing of HTML-rendered pages as well as JSON APIs.
- The architecture separates “transport + endpoint details” from command logic, so the same API client can be reused by CLI commands, web services, and scripts.
6. Domain subsystems
- Auth: login/status/import/logout flows, with support for cookies and tokens.
- Strategy: list/show/new/edit/delete strategies, including source-code handling and ID resolution quirks from JoinQuant pages.
- Backtest: run/list/show/stats/result/logs/delete for both formal backtests and compile-run mode.
- Community: list latest posts, fetch full post details, clone strategy from a post, and enrich with backtest stats.
- Each subsystem maps closely to a JoinQuant workflow, so the architecture is endpoint-driven rather than object-model-driven.
7. Output, errors, and machine-readable behavior
- jqcli/output.py standardizes table vs JSON rendering, and jqcli/errors.py normalizes user-facing failures into stable codes.
- The repo treats error handling as part of the public API: not authenticated, not found, usage error, network/API failure, file failure, confirmation required, and timeout each have distinct exit codes.
- This makes the CLI suitable for automation pipelines and downstream scripts that need deterministic failure semantics.
8. Web subapplication
- jqcli/web/app.py, routes.py, templates/*, and static/* form a server-rendered local UI.
- jqcli/web/db.py suggests a local persistence layer, while the web UI likely serves as an admin/inspection interface rather than a public-facing application.
- The web app is backed by the same domain concepts as the CLI, but with additional local orchestration around posts, jobs, and archival state.
9. Web services layer
- jqcli/web/services/* contains higher-level orchestration:
- archive_sync.py for incremental synchronizing of community data,
- posts.py / post_labels.py for post-centric storage and metadata,
- backtest_runner.py for managing backtest execution flows,
- strategy_download.py for retrieving strategy code,
- code_standardizer.py for normalizing source,
- jobs.py for background/job coordination.
- This layer is the bridge between the remote JoinQuant APIs and local persistent records, and it is where multi-step workflows are composed.
10. Scripts as operational pipelines
- scripts/archive_community_posts.py is the clearest batch pipeline in the repo: it syncs community lists, enriches details, and optionally hydrates backtest statistics into a canonical JSONL archive.
- The other scripts are inspection/probing tools used to reverse-engineer or validate JoinQuant behaviors and payload shapes.
- These scripts sit outside the CLI contract but reuse the same API and service boundaries, which indicates the project supports both ad hoc automation and repeatable data collection.
11. Data flow for the main use cases
- For strategy/backtest commands: user input → config/credential resolution → API client → JoinQuant page/API → parsed result → formatted output.
- For community archival: list page crawl → optional detail fetch → optional backtest stats fetch → local JSONL/database state → future incremental sync or UI display.
- For the web app: browser/UI request → local route handler → web service orchestration → remote JoinQuant API and/or local DB → rendered HTML/JSON.
12. Testing and repository boundaries
- tests/test_api, tests/test_commands, tests/test_web.py, and tests/test_config.py show the repo is organized around testing each boundary separately: transport parsing, CLI behavior, config precedence, and web behavior.
- This mirrors the architecture: API parsing is tested apart from command handling, and the web app is tested apart from the CLI.
- The presence of a design doc and progress tracking files also suggests the repo is under active evolution, with architecture decisions documented alongside implementation.
13. External service dependency
- The only major external system is JoinQuant itself; all interesting business behavior depends on its real login flow, server-rendered pages, and private JSON endpoints.
- The repo’s architecture is therefore best understood as a client and orchestration layer around JoinQuant, with local persistence and automation tooling added on top.
Main entry points: client.py HTTP client · cli.py CLI entry · auth.py Auth cmd · config.py Config
Components 22
CLI surface
Command-line entrypoint, routing, and user-facing automation contract.
- CLI entry · Root command entrypoint and argument dispatch.
jqcli/cli.py - Auth cmd · Login, status, import, and logout flows.
jqcli/commands/auth.py - Strategy cmd · Strategy CRUD and code handling commands.
jqcli/commands/strategy.py - Backtest cmd · Backtest and compile-run command flows.
jqcli/commands/backtest.py - Community cmd · Community post discovery and strategy cloning commands.
jqcli/commands/community.py - Web cmd · Starts or manages the local web application.
jqcli/commands/web.py
Core client
Shared config, transport, endpoint wrappers, and result handling.
- Config · Environment, persistent config, URL, timeout, and credential precedence.
jqcli/config.py - Errors · Stable exit codes and normalized failures.
jqcli/errors.py - Output · JSON and table rendering for CLI output.
jqcli/output.py - HTTP client · Shared request/session transport for JoinQuant access.
jqcli/api/client.py - Auth API · JoinQuant login and session management endpoints.
jqcli/api/auth.py - Strategy API · Strategy listing, editing, creation, and deletion endpoints.
jqcli/api/strategy.py - Backtest API · Formal backtest and compile-run endpoints plus result parsing.
jqcli/api/backtest.py - Community API · Community posts, post details, and enrichment endpoints.
jqcli/api/community.py
Web app
Local server-rendered UI and orchestration services.
Scripts and tests
Operational pipelines, probes, and boundary-focused tests.
- Archive script · Batch sync pipeline for community archive generation.
scripts/archive_community_posts.py - Probe scripts · Inspection scripts used to reverse-engineer and validate JoinQuant behavior.
scripts/probe_joinquant.py - Boundary tests · Tests for config, API parsing, command behavior, and web behavior.
tests
Other components
- JoinQuant · Remote web UI and private JSON endpoints that the repo automates.
Connections 37
- CLI entry → Auth cmd: routes · CLI dispatches auth subcommands.
- CLI entry → Strategy cmd: routes · CLI dispatches strategy subcommands.
- CLI entry → Backtest cmd: routes · CLI dispatches backtest subcommands.
- CLI entry → Community cmd: routes · CLI dispatches community subcommands.
- CLI entry → Web cmd: routes · CLI dispatches web subcommands.
- Auth cmd → Config: resolve auth · Commands load config and credential context.
- Strategy cmd → Config: resolve auth · Strategy commands depend on resolved config.
- Backtest cmd → Config: resolve auth · Backtest commands depend on resolved config.
- Community cmd → Config: resolve auth · Community commands depend on resolved config.
- Auth cmd → Auth API: calls · Auth commands delegate to auth API wrapper.
- Strategy cmd → Strategy API: calls · Strategy commands delegate to strategy API wrapper.
- Backtest cmd → Backtest API: calls · Backtest commands delegate to backtest API wrapper.
- Community cmd → Community API: calls · Community commands delegate to community API wrapper.
- Auth cmd → Output: renders · CLI formats auth results for JSON/table output.
- Strategy cmd → Output: renders · CLI formats strategy results for JSON/table output.
- Backtest cmd → Output: renders · CLI formats backtest results for JSON/table output.
- Community cmd → Output: renders · CLI formats community results for JSON/table output.
- Auth cmd → Errors: maps failures · Commands normalize user-facing failures to exit codes.
- HTTP client → JoinQuant: talks to · Shared transport targets JoinQuant.
- Auth API → HTTP client: uses · Auth endpoints use shared HTTP client.
- Strategy API → HTTP client: uses · Strategy endpoints use shared HTTP client.
- Backtest API → HTTP client: uses · Backtest endpoints use shared HTTP client.
- Community API → HTTP client: uses · Community endpoints use shared HTTP client.
- Auth API → JoinQuant: auth pages · Auth flows call remote login/session pages.
- Strategy API → JoinQuant: strategy pages · Strategy flows interact with remote pages and JSON.
- Backtest API → JoinQuant: backtest pages · Backtest flows interact with remote pages and JSON.
- Community API → JoinQuant: community pages · Community flows interact with remote pages and JSON.
- Web app → Routes: serves · Web app mounts route handlers.
- Routes → Web services: delegates · Routes delegate business logic to services.
- Web services → Local DB: persists · Services read and write local persistent state.
- Web services → HTTP client: reuses · Web workflows reuse shared transport to reach JoinQuant.
- Archive script → Community API: crawls · Archive pipeline fetches community list and details.
- Archive script → Local DB: writes archive · Archive pipeline can hydrate local canonical state.
- Probe scripts → HTTP client: probes · Inspection scripts exercise transport and parsing behavior.
- Boundary tests → Config: covers · Tests verify config precedence and resolution.
- Boundary tests → HTTP client: covers · Tests verify transport and parsing boundaries.
- Boundary tests → Web app: covers · Tests verify web behavior separately from CLI.