Repository navigation
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1153 +/- ##
==========================================
+ Coverage 95.66% 95.70% +0.04%
==========================================
Files 61 62 +1
Lines 6459 6593 +134
==========================================
+ Hits 6179 6310 +131
- Misses 280 283 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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)
standby_request for calling Standby Actorsstandby_request for calling Standby Actors, with per-request compression in HTTP clients
standby_request for calling Standby Actors, with per-request compression in HTTP clientsserver_request for calling Server Actors, with per-request compression in HTTP clients
server_request for calling Server Actors, with per-request compression in HTTP clientsserver_request for calling Server Actors endpoints
server_request for calling Server Actors endpointsserver_request for calling Server Actor endpoints
Pijukatel
left a comment
There was a problem hiding this comment.
Looks good to me.
Just an idea for consideration since this will be a new public way to work with server actors, we can carefully consider the options.
What if ServerActor would be a component of Actor? It would work a little bit around the name you are not sure about. Server Actor is clearly something different than normal Actor. Maybe we can make the distinction less blurry?
The methods and functionality related to the server would be nicely grouped together, not inflating the normal Actor.
So instead of
ActorClient.get_server_url
ActorClient.server_request
ActorClient.get_server_openapi_spec
You would get something like
ActorClient.server.get_url
ActorClient.server.request
ActorClient.server.get_openapi_spec
…the CLI and MCP server
…rop the httpx2 example
|
@Pijukatel Thanks, good idea, I've implemented it. The methods now live on a new Also tagging @janbuchar, since one more pair of eyes on the design of this new feature would be great. |
I like this implementation. It is well separated and even though the distinction is quite blurry on the platform, here it feels well separated. |
) - Adds `QueryParamValue` and `QueryParams` to `apify_client.types` and uses them for every `params` input in the client (`HttpClient.call`, `_build_params`, default params, wait and batch helpers), generalizing the inline type from #1153. - The union is exactly what the client converts or sends unchanged (`str`, `int`, `float`, `bool`, `Decimal`, `datetime`, `list[str]`, `None`); a list of non-strings raised `TypeError`, and a `timedelta`, tuple, enum or dict was sent as its repr, so both are now type errors. - Custom HTTP clients overriding `call` with `params: dict[str, Any] | None` should accept `QueryParams | None`; runtime behavior is unchanged. Co-authored-by: Claude <noreply@anthropic.com>
# Conflicts: # tests/unit/test_pluggable_http_client.py
… to HttpClient.call()
Adds
ActorClient.server()andActorClientAsync.server(), which return anActorServerClient/ActorServerClientAsyncfor Server Actors (formerly Actor Standby):request()sends a request to the Actor's server. The host always comes from the Actor'sstandbyUrl. The token goes in theX-Apify-Authorizationheader, which the platform strips, so headers the caller passes,Authorizationincluded, reach the Actor as they are.request()returns the server's response whatever its status. Only 429 and 503 are retried, since other statuses may come from the Actor's code. Network errors and timeouts aren't retried, since the Actor may have already handled the request. It raises only when it gets no response: the Actor doesn't exist or isn't a Server Actor, or the request fails or times out.request()sends bodies uncompressed unlesscompressionis set, returns the body unread withstream=True, and defaults to thelongtimeout to cover a cold start.get_url()returns the server URL. It's fetched once perActorClient, byget_url()orget_openapi_spec().get_openapi_spec()returns the web server schema from the build that serves the server (actorStandby.build, orlatest), orNoneif there's none. The schema field comes from fix(openapi): add missing fields to the Actor definition schema apify-docs#3115.get_url()andget_openapi_spec()take atimeout.ActorClient.standby()is a deprecated alias ofserver()and will be removed in v4.Other changes:
HttpClient.callandHttpClientAsync.calltake new arguments:compression,authorization_header,raise_for_status,retry_status_codes, andretry_transport_errors. A custom HTTP client that overridescallmust accept and honor them.ApifyClientErrorinto a nonexistentApifyClientAsyncError.Closes: #973
✍️ Drafted by Claude Code