Skip to content

Proposal: stable Python API for orchestration and programmatic consumption #52

Description

@careb36

Problem

OpenOSINT is currently optimized for interactive and tool-driven use via the CLI, REPL, and MCP surfaces. That is valuable for day-to-day investigations, but it makes the project difficult to consume as a library inside orchestration systems, automation pipelines, and higher-level OSINT applications.

Today, there is no stable public Python entry point that a caller can rely on for programmatic use. Downstream projects must reach into implementation details, follow migration-specific internal modules, or shell out to commands instead of importing a supported API.

This creates several practical problems:

  • orchestration / workflow engines cannot use OpenOSINT as a dependency with a stable contract
  • there is no clear interface for typed investigations (email, domain, username, IP, URL, person, etc.)
  • budget and timeout controls are not exposed in a public, documented way
  • it is difficult to integrate OpenOSINT with other systems without depending on CLI behavior
  • the project is effectively CLI-first rather than library-first for programmatic use cases

This is particularly relevant when OpenOSINT is used as one component in a larger investigation stack, where a coordinator or orchestrator may need to call the project directly from Python, pass a target and investigation budget, and inspect the resulting entity graph without going through the REPL or MCP layer.

Proposal

Introduce a small, documented public Python API that intentionally exposes a stable, high-level investigation contract while leaving the lower-level implementation details in place.

The goal is not to replace the current human-facing interfaces. Rather, the goal is to add a supported programmatic surface that is explicit, typed, and documented for downstream callers.

The proposal is to add a public investigate() entry point and a small set of supporting types that map to the existing investigation engine without exposing implementation internals.

In practice, this means:

  • openosint.investigate.investigate() becomes the supported high-level entry point
  • callers can pass a target string plus optional investigation kind and budget
  • callers can attach an optional run_id for correlation/logging
  • callers receive the same EntityGraph used internally, without having to know about private helpers or tool orchestration implementation details
  • the public API remains lightweight and avoids forcing every caller to understand the full pivot/graph subsystem

This keeps the current interactive surfaces intact while enabling a clean dependency path for orchestrators and agentic systems.

API contract

The intended public contract looks like:

importasynciofromopenosintimportinvestigatefromopenosint.graph.export.stiximportto_stix_jsongraph=asyncio.run(investigate("example.com"))
print(to_stix_json(graph))

The API can also support typed investigations:

importasynciofromopenosint.investigateimportinvestigate, InvestigationBudget, EntityKindbudget=InvestigationBudget(max_depth=3, max_entities=60, max_tool_calls=80)
graph=asyncio.run(
investigate(
"johndoe99",
kind=EntityKind.USERNAME,
budget=budget,
run_id="daily-2026-09-04",
)
)

Proposed public symbols:

  • openosint.investigate.investigate()
  • openosint.investigate.EntityKind
  • openosint.investigate.InvestigationBudget
  • package-root re-exports from openosint.__init__ for convenience

This keeps the interface narrow and stable while aligning with the project’s current graph model and investigation semantics.

Compatibility plan

This proposal is deliberately additive and compatibility-safe:

  1. Existing CLI, REPL, and MCP workflows remain unchanged.
  2. The public API sits on top of the current investigation engine instead of replacing it.
  3. The existing pivot.investigate_graph() remains the underlying implementation detail.
  4. The wrapper validates input and normalizes budget values before invocation.
  5. The public contract is intentionally small and documentation-friendly.
  6. STIX export and graph export remain optional, behind the existing extra dependencies, so current installations remain unaffected unless callers opt in.

This is a low-risk path because it does not require changing the current operational model or removing existing user interfaces. It simply provides the missing contract that external orchestration code needs to consume OpenOSINT in a supported, predictable way.

Why this matters

Adding a stable public API is not a cosmetic change. It is the difference between OpenOSINT being a local interactive tool and OpenOSINT being a reusable investigation primitive inside broader systems.

If we want OpenOSINT to be used as a dependency by orchestrators, automation frameworks, and downstream intelligence systems, then the library surface must be explicit and supported. This proposal gives maintainers a clear and minimal way to do that without destabilizing the current CLI-first experience.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions