Skip to main content
Once an actor is deployed, your own apps and scripts can read it and call it. There are three ways in, and the right one depends on what you’re building and who should pay: This page builds a counter actor and calls it all three ways.

The actor

Create the project. The last line removes a test for the starter actor you’re about to replace:
Output
Replace actors/counter/main.py with:
count_page and the routes line are for HTTP. Add the website’s files and a [web] table. The table needs schema_version = 4:
Run init, then one call, on your machine:
Output
To put it on Cloud, deploy it. The deploy also publishes web/, and to change the website’s files later, run cowboy deploy --web-only.

From Python

For a Python app, use cowboy-sdk, the client library, imported as cowboy. It needs Python 3.10 or later. Install it in your app’s environment:
CowboyClient is the client, and AsyncCowboyClient has the same methods, awaited.

Connect to Cloud

A client without a key can only read, which is enough to get started:
To call handlers, give it a key file and the network you expect:
Calls are paid from this wallet, so keep the key file out of your code and your repository. The network values are a safeguard: the client refuses to sign unless the endpoint matches them, so a wrong URL can’t spend your money.

Read the actor’s state

The examples from here on use that client. Reading is free and needs no key:
To read through a handler instead, run it read-only with actor_read:

Call a handler and wait for the result

A handler receives bytes, and encode, from cowboy.serialization, turns a Python value into them:
status is succeeded, reverted or timed_out. On succeeded, decoded() is the handler’s return value. On timed_out, the call may still go through. fee_paid is what the call cost, in base units (one CBY is a billion). If the call isn’t accepted, execute_actor_wait raises TransactionSkipped.

Follow events

get_actor_logs returns at most 50 events, oldest first. To follow new ones, pass reverse=True and poll, skipping events you’ve seen. block_height says when the event happened, where a block is the network’s unit of about one second.
Events are public, like the actor’s state.

From scripts

For scripts and CI jobs, every cowboy command takes --json and has fixed exit codes. See Script the CLI.

Over HTTP

An actor can answer HTTP requests, so browsers, webhooks and apps in any language can call it with no Cowboy library.

Handlers as routes

@get("/api/count") makes count_page answer GET /api/count, and cowboy_sdk.routes also has post, put, patch, delete and head (SDK reference). A route handler needs @public, because a route decorator grants no access by itself. It sees the gateway as the caller, not the visitor, so don’t trust self.sender here. The handler gets the request as a dict, with method, path, path_params, query, headers (a list of [name, value] pairs) and body (bytes). It returns the response as a dict too, with status, headers and body. GET and HEAD requests run the handler read-only. Other verbs can change state. Try the handler on your machine:
Output
body is the bytes of {"count": 5}.

Static files

mount("/*", volume="web", fallback="index.html") serves the actor’s website from the volume that cowboy deploy publishes web/ to. / serves index.html, and /about.html serves about.html. Any path with no file serves the fallback, and if you leave fallback out, it answers 404. /api/count still reaches count_page, because the longer match wins. cowboy check lists the routes the deploy installs:
Output
actor pays means visitors pay nothing and need no wallet.

The actor’s address on the web

An actor with routes answers at https://<actor address>.cloud.cowboy.inc/, with the full address in lowercase. cowboy deploy prints it on the Gateway line. The site starts owner-only, whatever its handlers allow. To open it to everyone, publish it:
Output
The curl answers with the count as JSON.

Next