Skip to main content

summonpot

Summonpot

Declare deterministic operations and agentic decisions through one framework.

A contract-first Python framework for combining application-owned execution and agent-owned choices in one typed HTTP API, with simple, fully contract-based endpoints.

CI PyPI version Python versions MIT License Join the ModePot Discord GitHub stars

Quick start · Why summonpot · Capabilities · How it works · Examples · Community · Contributing

One Summonpot application branches into the exact shipped single-operation direct slice or an agent-backed endpoint through the same typed HTTP and OpenAPI framework

Summonpot modernizes APIs for AI without replacing the endpoint with a separate agent layer. The endpoint remains the stable public abstraction while its contract combines exact application behavior with explicitly bounded agentic decisions.

The ellipsis is declaration syntax, not an unfinished implementation. The signature, docstring, operations, argument bindings, and return type are the executable contract. Depends(...) and Required(...) attach deterministic application code. AgentChoice() marks the exact arguments where the agent may decide. Deterministic and agentic endpoints use the same declaration style, request/response validation, routing, and OpenAPI instead of separate API and agent frameworks. Summonpot owns the bounded agent loop, operation enforcement, and structured output. Calling a registered declaration directly raises a clear error; serve the application or invoke its generated HTTP route instead.

Why summonpot?

A conventional API puts deterministic work in a handler. An agent-first stack starts from an agent workflow and then wraps it in HTTP. Summonpot declares both through the same contract-first framework, so applications keep one public API as the balance changes between exact operations and semantic decisions:

The following conceptual declaration omits the application-specific models and service implementation; the quick start is the standalone example.

from typing import Literal

from summonpot import AgentChoice, Exactly, FromRequest, Operation, Required, Summon


summon = Summon("research-api")


def build_deterministic_report(topic: str) -> ResearchResponse:
    """Run the application's fully resolved research operation."""
    return research_service.build_response(topic=topic, format="detailed")


deterministic_report_operation = Operation(
    build_deterministic_report,
    bind={"topic": FromRequest("topic")},
    output=ResearchResponse,
)


def build_agentic_report(
    topic: str,
    format: Literal["summary", "detailed"],
) -> ResearchReport:
    """Run the exact operation with one declared semantic choice."""
    return research_service.build(topic=topic, format=format)


agentic_report_operation = Operation(
    build_agentic_report,
    bind={
        "topic": FromRequest("topic"),
        "format": AgentChoice(),
    },
    output=ResearchReport,
)


@summon("/reports/deterministic")
def deterministic_report(
    request: ResearchRequest,
    report=Required(deterministic_report_operation, calls=Exactly(1)),
) -> ResearchResponse:
    """Return the detailed report through a fully resolved operation path."""
    ...


@summon("/reports/agentic")
def agentic_report(
    request: ResearchRequest,
    report=Required(agentic_report_operation, calls=Exactly(1)),
) -> ResearchResponse:
    """Choose the report format and return the sourced report."""
    ...

Those declarations answer the questions an API framework needs to answer:

Question Declared by
What may the caller send? ResearchRequest
What must the endpoint achieve? The docstring
What application authority may execution use? Depends(...) and Required(...)
Which inputs must come from trusted application data? FromRequest(...) and other bindings
Where may the agent make a semantic choice? Explicit AgentChoice(...) bindings
What may the endpoint return? ResearchResponse
Where is orchestration code? Owned by summonpot

The request carries business data only. The endpoint goal is fixed in code. Exact operations remain application-owned, while the agent can choose only within the authority declared for that endpoint. A response is not accepted until every Required(...) operation has completed successfully.

Conventional APIs Agent-first stacks summonpot
Mental model Write a handler Configure an agent Declare one endpoint
Deterministic work Handler code Usually exposed as tools Exact application-owned operations
Agentic decisions Separate agent workflow Primary abstraction Explicit choices in the same declaration
HTTP Built around the handler Added around the agent Generated from the declaration
Application authority Held by handler code Often assembled separately Closed by the endpoint contract
Final output Handler convention Provider or framework convention Locally validated response model

One declaration style, both endpoint flows

/reports/deterministic binds every operation argument to validated application data; its operation output is exactly the endpoint response model, so the fully resolved endpoint executes once without constructing a model. /reports/agentic uses the same declaration style but adds one explicit AgentChoice(). The endpoint with AgentChoice() still uses the agent runtime. Both keep typed request/response contracts, operation enforcement, routing, and OpenAPI under Summonpot.

What ships today

  • One declaration style for deterministic operations and agentic decisions, sharing the same request, response, route, validation, and OpenAPI contract.
  • Contract-first endpoints with a required goal and typed request/response contracts.
  • Closed capability sets made from exact application-owned callables.
  • Optional and mandatory operations through Depends(...) and Required(...).
  • Runtime-enforced required use, tracked per request rather than trusted to a prompt.
  • Per-request operation-start enforcement for the first complete runtime slice: trusted FromRequest values and callable defaults are removed from the operation tool schema, direct AgentChoice arguments remain visible, one permitted start per request is reserved before application code, and output= is locally validated before success. This is not a distributed exactly-once completion guarantee.
  • Single-operation deterministic execution when one required Exactly(1) operation uses a Pydantic request model and has at least one FromRequest binding; every remaining argument comes from FromRequest or an immutable identity-stable callable default, and its output is exactly the endpoint response model. This path does not resolve, construct, or call a model.
  • Typed Operation contracts for the admitted single-operation slice, with exact built-in FromRequest and direct AgentChoice sources. The broader public source vocabulary remains available for future execution slices but is rejected at endpoint registration when the runtime cannot enforce it.
  • Registration-time contract validation that rejects missing sources, invalid result references, unsupported choices, and provably incompatible types before serving.
  • Provider-neutral model selection for OpenAI, Anthropic, Google, Groq, Mistral, OpenRouter, and xAI.
  • Generated HTTP and OpenAPI contracts for body and query endpoints.
  • Stable OpenAPI operationId values derived from each endpoint's declared name and HTTP method, with registration-time rejection when two routes would produce the same ID.
  • GET, POST, PUT, PATCH, DELETE, and HEAD routes, keyed by (path, method).
  • Local response validation, bounded retries, usage limits, timeouts, and redacted public failures.
  • A keyless test model for exercising routes and schemas before adding provider credentials.
  • Coding-agent skills for Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and OpenAI Codex, including typed operation bindings and their current runtime boundary.

Quick start

1. Install

pip install "summonpot[serve,cli]"

Python 3.11 through 3.13 is supported. Summonpot requires Pydantic >=2.13.5,<2.14 and pydantic-core >=2.46.5,<2.47. Earlier Pydantic versions are no longer supported. Output revalidation uses a version-sensitive core option to avoid reusing validators that trust existing model instances; the dependency bounds keep that integration on the tested minor versions.

Start without a provider account by selecting the built-in test model:

export SUMMONPOT_MODEL=test

The test model is keyless, not side-effect-free. An endpoint with capabilities may call them using generated placeholder arguments. Use harmless capabilities when testing wiring; do not attach destructive operations or treat the model as a dry-run sandbox.

2. Declare an endpoint

Create app.py:

from typing import Literal

from pydantic import BaseModel, Field
from summonpot import Summon


class ReviewRequest(BaseModel):
    text: str = Field(min_length=1, max_length=2_000)


class ReviewResponse(BaseModel):
    sentiment: Literal["positive", "negative", "neutral"]
    summary: str


summon = Summon("review-api")


@summon("/review")
def review(request: ReviewRequest) -> ReviewResponse:
    """Classify the text's sentiment and summarize it in one short sentence."""
    ...

The ellipsis marks a complete endpoint declaration. Summonpot never calls that body, and direct Python calls are rejected at the decorator boundary.

3. Serve it

summonpot serve app.py --host 127.0.0.1 --port 8000

Open the generated API documentation at http://127.0.0.1:8000/docs, or call the endpoint directly:

curl -X POST http://127.0.0.1:8000/review \
  -H 'Content-Type: application/json' \
  -d '{"text":"The endpoint contract is surprisingly small."}'

The test model returns schema-valid placeholder data. To receive a real agent-generated answer, install a provider extra and select a provider-qualified model:

pip install "summonpot[serve,cli,anthropic]"
export SUMMONPOT_MODEL=anthropic:claude-sonnet-4-5
export ANTHROPIC_API_KEY='<your key>'

The endpoint code and HTTP contract do not change when the provider changes.

Exact capabilities, not ambient authority

A capability is ordinary application code. It runs for real; summonpot never replaces its implementation.

def calculate_quote(
    unit_price_cents: int,
    quantity: int,
    tax_rate_percent: str,
) -> dict[str, int]:
    """Calculate an exact quote using the service's approved pricing rules."""
    return pricing_service.calculate(
        unit_price_cents=unit_price_cents,
        quantity=quantity,
        tax_rate_percent=tax_rate_percent,
    )

Attach it to one endpoint, continuing from the application and models defined above:

from summonpot import Required


@summon("/quotes")
def create_quote(
    request: QuoteRequest,
    calculation=Required(calculate_quote),
) -> QuoteResponse:
    """Calculate and return the exact approved quote."""
    ...
Declaration Runtime contract
Depends(operation) The operation is available to the endpoint and may be called.
Required(operation) Final output is rejected until the operation succeeds.

For bare callables, Required(...) proves only that the operation returned successfully at least once during that request. The narrow bound form shown below additionally enforces trusted request injection, local operation-output validation, and Exactly(1). Ordering, idempotency, and provenance-backed final claims remain separate concerns.

Capabilities do not become request-body fields or OpenAPI parameters. Their docstrings and annotations define the tool schema visible to the agent, while their implementations define the real application behavior.

The capability set is closed. For one required typed operation with explicit Exactly(1), the runtime injects FromRequest values, removes them and callable defaults from any model-visible tool schema, validates the declared operation output, and rejects a second start. If the endpoint uses a Pydantic request model, has at least one FromRequest binding, uses only FromRequest or supported immutable callable defaults, and that output is exactly the endpoint response model, Summonpot executes the operation directly. Otherwise direct AgentChoice arguments remain visible to the agent. Request values on agentic paths still appear in the agent's user message; tool-schema hiding is not prompt secrecy. Unsupported explicit operation shapes are rejected before serving until their execution semantics ship. Bare Depends(fn) and Required(fn) declarations with implicit marker bounds keep their legacy agent behavior.

Before either supported path invokes the capability, each injected FromRequest value is checked strictly against its receiving operation parameter, including Annotated constraints. A broader request contract therefore does not authorize a narrower operation parameter. The check runs strictly before application code starts and rejects coercion: a valid canonical validated request value is passed through unchanged, not replaced by a coerced value. It does not rerun request-model validators.

The supported receiver vocabulary is exact primitive types with common non-transforming numeric constraints and non-pattern string constraints, primitive Literal values with exact-type semantics, unions when any branch safely matches, recursively checked built-in containers, and structurally checked Pydantic model instances. The predicate uses unbound built-in container operations, does not rebuild sets or dictionaries, and never calls a serializer. Receiver models with typed extra="allow" fields have those extras checked structurally too. Bare Decimal receivers require finite values before bounds or multiple_of are checked. Decimal allow_inf_nan=True, float multiple_of, enum receiver contracts, callable discriminators, and string pattern constraints are rejected at registration because the hook-free predicate cannot reproduce their semantics exactly; non-pattern string constraints remain supported. Integer and finite Decimal multiple_of constraints remain supported. Receiver schemas containing custom functional validators (BeforeValidator, AfterValidator, WrapValidator, or PlainValidator), transforming string constraints, custom literal values, custom instance-checking metaclasses, or unsupported core schemas are rejected at registration rather than silently stripped. Every operation must still enforce authorization. Pass exact operations, never raw database sessions, engines, connections, cursors, arbitrary SQL, shell access, or ambient filesystem authority.

See the complete executable Required(...) quote example.

Typed operation contracts fail before serving

Use Operation when a capability's dataflow is part of the endpoint contract rather than something the agent should invent:

from my_service.models import Customer, CustomerRequest, CustomerResponse
from my_service.operations import load_customer
from summonpot import AgentChoice, Exactly, FromRequest, Operation, Required, Summon


summon = Summon("customer-api")

customer_from_request = Operation(
    load_customer,
    bind={
        "customer_id": FromRequest("customer_id"),
        "format": AgentChoice(),
    },
    output=Customer,
)


@summon("/customers")
def get_customer(
    request: CustomerRequest,
    customer=Required(customer_from_request, calls=Exactly(1)),
) -> CustomerResponse:
    """Load this customer and return the approved customer view."""
    ...

The contract is immutable after construction. At registration, summonpot verifies that:

  • every required operation argument has an explicit source;
  • FromRequest(...) names a real request field;
  • FromResult(...) names a declared producer and a readable, typed output field;
  • AgentChoice(...) selects from a supported collection and fits its receiving argument;
  • known source, element, and destination types are compatible; and
  • ordering references name operations declared by the same endpoint.

The rule is deliberately conservative: a declaration is rejected only when its incompatibility is provable. Missing annotations, Any, framework context, and type relationships the checker cannot establish remain unknown rather than becoming false registration errors. An annotation that names a type Python cannot resolve is still an invalid endpoint declaration and fails at import.

For example, binding an int request field to a str operation argument fails while the module is imported. A Customer value may feed a Person argument when Customer is a subclass, and Python's numeric widening permits int or bool to feed float.

How it works today

HTTP request
    |
    v
Pydantic request validation + OpenAPI contract
    |
    v
Runtime.call(...)
    |
    +---- one fully resolved Exactly(1) operation
    |          |
    |          +---- execute directly; validate declared output
    |
    +---- otherwise: configured provider-neutral model
               |
               +---- may call only declared capabilities
               |
               +---- Required-operation gate
    |
    v
Local Pydantic response validation
    |
    v
HTTP response

The endpoint docstring becomes the fixed execution goal. Request data becomes validated execution input. Capabilities become the complete set of operations available to execution. The response model is always the final local validator; on the agent-backed path, it also becomes the structured-output schema and validated request data becomes the user message. Every endpoint response model and every declared operation output= shape is checked before serving, including operation shapes outside the currently enforced runtime slice. Enabled direct validation aliases cannot claim the same input key under the model's configured validation policy, and declared fields plus serialization aliases cannot emit duplicate JSON keys. Runtime-enforced model output also rejects allowed extras from instances or raw mappings that shadow a canonical field or emitted alias, while retaining noncolliding validated extras. This namespace admission does not imply runtime structural validation for broader operation graphs, whose execution remains unsupported.

Raw Runtime.call(endpoint, mapping) invocations validate that mapping once against the same declared request contract as HTTP, including required fields, defaults, aliases, and canonical typed values for both Pydantic request models and individual parameters. The HTTP adapter still validates at its transport boundary and hands its plan-bound value graph to the runtime once; runtime preparation does not rerun those validators. Raw preparation does not render canonical values through Pydantic field serializers or application copy/string hooks. Parameterless endpoints accept only an empty raw mapping, rejecting undeclared keys before model execution or application value hooks; their HTTP routes expose no request fields.

Pydantic AI is an internal runtime dependency. Applications use Summon, @summon, Pydantic models, and declarative capabilities; they do not construct provider clients or Pydantic AI agents.

The contract stays stable across execution paths

Summonpot chooses its current execution path without adding a second endpoint API:

Contract state Current execution
Pydantic request model, one required Exactly(1) operation, at least one FromRequest binding, only FromRequest or immutable identity-stable defaults, exact response-model output Execute directly without a model
A direct AgentChoice remains in the admitted single-operation shape Use the agent runtime with the enforced operation contract
Bare callable capabilities with implicit marker bounds Use the legacy agent runtime
Unsupported explicit binding, ordering, bound, output, or multi-operation shape Reject during registration

Broader graph execution and ordering, multi-operation deterministic execution, SQLAlchemy/SQLite operation adapters, write receipts, streaming, and built-in authentication are planned, not shipped. See ROADMAP.md for the design boundaries and implementation order.

Supported immutable callable defaults are exact built-in None, bool, int, float, complex, str, and bytes values, plus tuples and frozensets containing only those values recursively. Custom types (including subclasses of those built-ins) and mutable defaults keep the endpoint agent-backed; copy hooks are not proof of immutability. Scalar request declarations also remain agent-backed.

HTTP methods and OpenAPI

POST is the default. Body endpoints take one Pydantic request model. Bodyless methods such as GET, DELETE, and HEAD declare scalar or scalar-sequence query parameters:

This fragment continues from an existing module-level summon application:

from typing import Literal

from pydantic import BaseModel


class TicketPage(BaseModel):
    tickets: list[str]


@summon("/tickets", method="GET")
def list_tickets(
    status: Literal["open", "closed"] = "open",
    ids: list[int] | None = None,
) -> TicketPage:
    """List tickets matching the requested filters."""
    ...

GET /tickets and POST /tickets may coexist. Registering the same normalized (path, method) twice fails at import time, as do missing docstrings, unresolved type annotations, invalid capability callables, duplicate capability names, unsupported query types, and stream=True.

Path parameters

A {name} placeholder in a route binds from the URL on every method, body-carrying ones included. Each placeholder must match exactly one required scalar parameter (str, int, float, bool, UUID):

@summon("/customers/{customer_id}", method="POST")
def update_customer(customer_id: int, name: str) -> str:
    """Update one customer."""
    ...

customer_id is documented as an OpenAPI path parameter and is excluded from the generated request body model, so the value exists in exactly one place. The URL is the only authority for it: a body that also carries customer_id does not override the URL.

When the URL owns every declared parameter the route carries no request body at all, so it is callable with nothing but its path segments:

@summon("/items/{item_id}", method="POST")
def touch_item(item_id: int) -> Item:
    """Touch one item."""
    ...
curl -X POST http://localhost:8000/items/7

These fail at import time, next to the other registration errors above: a placeholder with no matching parameter, the same placeholder twice, a path parameter with a default, and a path parameter annotated with anything but a supported scalar. A structured value belongs in the body.

Provider and model configuration

Provider Install extra Model example API-key variable
OpenAI summonpot[openai] openai:gpt-4o-mini OPENAI_API_KEY
Anthropic summonpot[anthropic] anthropic:claude-sonnet-4-5 ANTHROPIC_API_KEY
Google summonpot[google] google:gemini-2.5-flash GOOGLE_API_KEY
Groq summonpot[groq] groq:llama-3.3-70b-versatile GROQ_API_KEY
Mistral summonpot[mistral] mistral:mistral-large-latest MISTRAL_API_KEY
OpenRouter summonpot[openrouter] openrouter:anthropic/claude-sonnet-4 OPENROUTER_API_KEY
xAI summonpot[xai] xai:grok-4 XAI_API_KEY

Set one default for the Summon application through SUMMONPOT_MODEL or in Python:

summon = Summon("research-api", model="openrouter:anthropic/claude-sonnet-4")

Override it for one endpoint without changing that endpoint's HTTP contract:

@summon("/research", model="anthropic:claude-sonnet-4-5")
def research(request: ResearchRequest) -> ResearchResponse:
    """Research the topic and return a sourced report."""
    ...

OpenRouter keeps the upstream provider and model after the first colon. Legacy unprefixed model names resolve through OpenAI for backward compatibility.

Bounding a call

Binding and exposure: A reachable endpoint can spend the operator's provider credit, so set explicit usage limits and a timeout:

from summonpot import Summon, UsageLimits
from summonpot.runtime import Runtime


summon = Summon(
    "my-service",
    runtime=Runtime(
        usage_limits=UsageLimits(
            request_limit=8,
            total_tokens_limit=40_000,
        ),
        timeout=30.0,
    ),
)
HTTP status Public meaning
422 Request validation failed.
429 The configured usage limit or provider rate limit was exceeded.
502 The provider failed or the agent did not satisfy the endpoint contract.
504 The endpoint exceeded its timeout.
500 Provider configuration or application capability failed.

Provider text, agent output, and capability details stay in operator logs rather than public error bodies.

The timeout bounds how long summonpot waits. It cannot terminate a synchronous capability already running in a worker thread, so give irreversible or long-running operations an internal deadline and idempotency policy of their own. Open thread-affine resources such as default SQLite connections inside the capability call rather than capturing them outside it.

Summonpot currently has no authentication layer. Bind local development to 127.0.0.1. Before exposing a service, put authentication in front of it and configure runtime limits.

Examples

The examples/ directory grows from one endpoint to a multi-file service:

Level Example What it demonstrates
1 basic_app.py Minimal typed request and response
2 02_required_capability.py Required exact calculation
3 03_agentic_order.py Bounded choice plus a required write
4 04_http_methods.py GET/POST routing and query parameters
5 05_bounded_runtime.py Limits, timeout, and model override
6 06_support_service/ Multi-file legacy capabilities and persisted ticket
7 07_bound_operation.py Enforced FromRequest + AgentChoice with Exactly(1)
8 08_direct_execution.py Credential-free single-operation deterministic execution
9 09_contract_boundaries/ Fail-closed registration, receiving constraints, output namespaces, and raw/HTTP parity

The examples guide includes a real HTTP call for every level and explains what runs today and what remains planned.

Give your coding agent the contract

Summonpot uses an ellipsis as a declaration body, which is easy for a coding agent to mistake for an unfinished handler. Install the bundled skill so the agent knows the endpoint shape, typed operation sources, registration rules, capability boundary, HTTP behavior, and runtime caveats:

summonpot add skills

With no arguments, summonpot detects agent configuration already present in the project. Choose one explicitly when needed:

summonpot add skills --agent claude
summonpot add skills --agent cursor
summonpot add skills --agent windsurf
summonpot add skills --agent copilot
summonpot add skills --agent cline
summonpot add skills --agent codex

Use --path ./myproject to target another project directory. Shared files such as AGENTS.md and .github/copilot-instructions.md are updated inside a managed block so surrounding project instructions remain intact.

Community

The ModePot Discord is the shared community for summonpot, intpot, dexpot, and the rest of the project family. Join to discuss use cases, ask implementation questions, and help shape declaration-first Python frameworks.

Use GitHub issues for reproducible bugs and scoped feature proposals. Use Discord for open-ended design discussion, early ideas, and help applying the frameworks to real projects.

Contributing

Summonpot is early enough that a focused contribution can still shape the framework, not just polish its edges.

Useful places to contribute include:

  • executable examples for real application workflows;
  • provider and HTTP acceptance coverage;
  • clearer errors, safer defaults, and API ergonomics;
  • FromResult/FromContext binding, broader capability-graph execution, and ordering;
  • exact database-operation adapters;
  • broader deterministic execution compilation described in the roadmap;
  • documentation, diagrams, and reproducible bug reports.

For substantial behavior or architecture changes, open an issue first so the public contract and security boundary stay coherent.

Development uses uv:

git clone https://github.com/tugrulguner/summonpot.git
cd summonpot
uv sync --all-extras
make check

Every user-facing change needs an issue-backed or generated orphan Towncrier fragment. Read CONTRIBUTING.md before opening a pull request.

Roadmap

The long-term goal is one stable endpoint declaration with the least-powerful sufficient executor behind it:

one fully resolved operation path  -> no-model deterministic executor
bounded semantic choice remains    -> agentic executor
no legal path                      -> typed deterministic error

The ordering, security constraints, non-goals, and shipped foundation live in ROADMAP.md.

Help summonpot grow

If the endpoint-first approach is useful to you:

  • Star the repository so more Python developers can find it.
  • Build one small endpoint and report the friction.
  • Share a real use case, add an executable example, or contribute to a roadmap milestone.

Early feedback is especially valuable because the public contract is small and the next execution layers are being designed around it now.

License

MIT

Release files for summonpot 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for summonpot 0.9.0
File Size Uploaded
summonpot-0.9.0.tar.gz 3.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for summonpot 0.9.0
File Interpreter ABI Platform
summonpot-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.3 MB

Release files / summonpot-0.9.0.tar.gz

Download URL summonpot-0.9.0.tar.gz
Size 3.2 MB
Tags Source
SHA-256 checksum
How to use checksums
78a58fb5bff6b16d83b74b96cd80294969c7ae728e9b17823ae70c86ea8d79d2
BLAKE2b-256 checksum
How to use checksums
17a1adc6740dc7a9c0cc1e964f15cd7f05e4532a1910249d93dafe3da0091b35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / summonpot-0.9.0-py3-none-any.whl

Download URL summonpot-0.9.0-py3-none-any.whl
Size 94.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
54ea2ce09aec9692932a04962f62f934e76b406bce5df88c1e798cd886cbc05e
BLAKE2b-256 checksum
How to use checksums
e75bd79735dd00d134c8757291f8b2757f4532c0d28b4e21eb8459a0246d55a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page