Skip to content

feat: add Server Actor support to Actor clients - #1153

Open
vdusek wants to merge 22 commits into
masterfrom
feat/standby-request
Open

vdusek wants to merge 22 commits into
masterfrom
feat/standby-request

Conversation

@vdusek

@vdusek vdusek commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds three methods to ActorClient and ActorClientAsync for working with Server Actors:

  • server_request() sends an HTTP request to the Actor's server without looking up its URL or attaching the token by hand.
  • get_server_url() returns the server URL (the Actor's standbyUrl), for calling the server with another HTTP client.
  • get_server_openapi_spec() returns the server's OpenAPI specification (the web server schema from the Actor's definition), for generating such a client.
actor = client.actor('username/actor-name')
response = actor.server_request('/search', params={'q': 'apify'})
spec = actor.get_server_openapi_spec()

server_request follows the CLI RFC (apify/apify-cli#1299):

  • The caller passes a path. The host always comes from the Actor's standbyUrl, and the token goes in the Authorization header, which the platform strips before forwarding.
  • Request bodies are uncompressed by default, and compression opts in. The timeout defaults to long to cover a cold start.
  • Error statuses raise ApifyApiError, and 5xx/429 are retried like API calls.

get_server_openapi_spec reads the spec from the build the Actor runs in Server mode: actorStandby.build (a tag or a build number), or latest if none is set. It returns None when the build has no web server schema. The schema field comes from apify/apify-docs#3115.

To support compression per request, HttpClient.call and HttpClientAsync.call take a new compression argument. A custom HTTP client that overrides call must accept it.

Also fixes the docstring sync script turning ApifyClientError into a nonexistent ApifyClientAsyncError, and adds a Server Actors concepts page.

Closes: #973

✍️ Drafted by Claude Code

@vdusek vdusek added the t-tooling Issues with this label are in the ownership of the tooling team. label Oct 19, 2026
@vdusek vdusek self-assigned this Oct 19, 2026
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.05263% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.55%. Comparing base (d1bc83a) to head (0addab8).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/apify_client/_resource_clients/actor.py 95.83% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1153   +/-   ##
=======================================
  Coverage   95.55%   95.55%           
=======================================
  Files          61       61           
  Lines        6004     6077   +73     
=======================================
+ Hits         5737     5807   +70     
- Misses        267      270    +3     
Flag Coverage Δ
integration 89.74% <18.42%> (-1.08%) ⬇️
unit 90.04% <96.05%> (+0.20%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

vdusek added a commit to apify/apify-docs that referenced this pull request Oct 20, 2026
While working on better support for calling Standby Actors from the API
client (apify/apify-client-python#1153), I couldn't find an explanation
of how the authentication headers are handled (Maybe I just missed it?).
I have two questions:

1. Does the Apify token reach the Actor's code? (It shouldn't.).
2. If an Actor needs its own authentication header, what's the best
practice for sending it? Is it `X-Apify-Authorization`?

I drafted a change; see the diff and suggest better/correct/more precise
explanation. Thank you.

(tagging @mvolfik, as I know a lot of the work there was done by you)
@vdusek
vdusek requested review from Pijukatel and removed request for Pijukatel October 20, 2026 06:58
@vdusek vdusek changed the title feat: add standby_request for calling Standby Actors feat: add standby_request for calling Standby Actors, with per-request compression in HTTP clients Oct 20, 2026
@vdusek vdusek changed the title feat: add standby_request for calling Standby Actors, with per-request compression in HTTP clients feat: add server_request for calling Server Actors, with per-request compression in HTTP clients Oct 23, 2026
@vdusek vdusek changed the title feat: add server_request for calling Server Actors, with per-request compression in HTTP clients feat: add server_request for calling Server Actors endpoints Oct 26, 2026
@vdusek vdusek changed the title feat: add server_request for calling Server Actors endpoints feat: add server_request for calling Server Actor endpoints Oct 26, 2026
@vdusek
vdusek requested review from Pijukatel and janbuchar October 26, 2026 07:40
@vdusek
vdusek marked this pull request as ready for review October 26, 2026 07:40
@vdusek
vdusek requested a review from szaganek as a code owner October 26, 2026 07:40
@apify-service-account apify-service-account added the tested Temporary label used only programatically for some analytics. label Oct 26, 2026

return True

async def server_request(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the name server_request 😄, but couldn't come up with anything better... Happy to hear your ideas.

@Pijukatel Pijukatel left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not sure about the ideal way to support server actors. Those can be of very different categories:

  1. Full app for browser
  2. Simple one endpoint API
  3. Complex API with many endpoints and full OpenAPI specification
  4. ...?

I think this change fits very well the 2. usecase, while its utility drops for the others.

What will be the natural way to work with usecase 3? I guess it could be actually generating that actor-server specific API client and using that. The only thing needed for that is the proper URL

So as mentioned in the Slack discussion in the issue description, I would probably also add these 2 methods:

  • get_server_actor_url as a generally useful method (just a visible alias to fetch something from configuration and double checking it is really a server actor)
  • get_server_actor_openapi_spec to properly support 3

Comment thread src/apify_client/_resource_clients/actor.py Outdated
Comment thread src/apify_client/_resource_clients/actor.py Outdated
Comment thread src/apify_client/_resource_clients/actor.py Outdated
@vdusek

vdusek commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

open api specs need apify/apify-docs#3115

vdusek added a commit to apify/apify-docs that referenced this pull request Oct 26, 2026
The build stores the whole `actor.json` as `actorDefinition`, and `GET
/actor-builds/{buildId}` returns it in full, but the schema only
described part of it. This adds the missing fields: `title`,
`description`, `meta`, `output`, `storages.datasets`,
`storages.keyValueStore`, `webServerSchema`, and `webServerMcpPath`.

`meta` lives in its own `ActorDefinitionMeta` schema so generated
clients get a named model for it.

The Python client needs `webServerSchema` to read a Server Actor's
OpenAPI spec (apify/apify-client-python#1153). I checked the generated
Python models against this spec, and the client's type check and unit
tests pass.

*✍️ Drafted by Claude Code*
@vdusek vdusek changed the title feat: add server_request for calling Server Actor endpoints feat: add Server Actor support to Actor clients Oct 26, 2026
@vdusek
vdusek requested a review from Pijukatel October 26, 2026 14:16

This branch has not been deployed

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

Labels

t-tooling Issues with this label are in the ownership of the tooling team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for standby Actors

3 participants