Skip to content

Commit 914eb0a

Browse files
committed
Merge branch 'master' into test-json-typing
2 parents a89de6d + 1edc546 commit 914eb0a

36 files changed

Lines changed: 138 additions & 131 deletions
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Package check
2+
3+
on:
4+
# Runs when manually triggered from the GitHub UI.
5+
workflow_dispatch:
6+
7+
# Runs when invoked by another workflow.
8+
workflow_call:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
package_check:
15+
name: Package check
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v6
20+
21+
- name: Set up uv package manager
22+
uses: astral-sh/setup-uv@v8.1.0
23+
with:
24+
python-version: "3.14"
25+
26+
- name: Build sdist and wheel
27+
run: uv run poe build
28+
29+
- name: Verify built package
30+
uses: apify/actions/python-package-check@v1.1.0
31+
with:
32+
package_name: apify
33+
dist_dir: dist
34+
python_version: "3.14"
35+
smoke_code: |
36+
from apify import Actor, Configuration, ProxyConfiguration
37+
Configuration()
38+
ProxyConfiguration()

.github/workflows/manual_release_beta.yaml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Beta release
22

33
on:
44
# Runs when manually triggered from the GitHub UI, or dispatched from `on_master.yaml`
5-
# via the `apify/workflows/execute-workflow` action for the automatic beta release on push to master.
5+
# via the `apify/actions/execute-workflow` action for the automatic beta release on push to master.
66
# Note: This workflow is intentionally NOT a reusable workflow (no `workflow_call`) because PyPI's
77
# Trusted Publishing does not currently support reusable workflows.
88
# See: https://docs.pypi.org/trusted-publishers/troubleshooting/#reusable-workflows-on-github
@@ -23,7 +23,7 @@ jobs:
2323
version_number: ${{ steps.release_prepare.outputs.version_number }}
2424
changelog: ${{ steps.release_prepare.outputs.changelog }}
2525
steps:
26-
- uses: apify/workflows/git-cliff-release@main
26+
- uses: apify/actions/git-cliff-release@v1.1.2
2727
id: release_prepare
2828
name: Release prepare
2929
with:
@@ -53,13 +53,24 @@ jobs:
5353
url: https://pypi.org/project/apify
5454
steps:
5555
- name: Prepare distribution
56-
uses: apify/workflows/prepare-pypi-distribution@main
56+
uses: apify/actions/prepare-pypi-distribution@v1.1.2
5757
with:
5858
package_name: apify
5959
is_prerelease: "yes"
6060
version_number: ${{ needs.release_prepare.outputs.version_number }}
6161
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}
6262

63+
- name: Verify built package
64+
uses: apify/actions/python-package-check@v1.1.0
65+
with:
66+
package_name: apify
67+
dist_dir: dist
68+
python_version: "3.14"
69+
smoke_code: |
70+
from apify import Actor, Configuration, ProxyConfiguration
71+
Configuration()
72+
ProxyConfiguration()
73+
6374
# Publish the package to PyPI using PyPA official GitHub action with OIDC authentication.
6475
- name: Publish package to PyPI
6576
uses: pypa/gh-action-pypi-publish@release/v1
@@ -72,7 +83,4 @@ jobs:
7283
pages: write
7384
id-token: write
7485
uses: ./.github/workflows/manual_release_docs.yaml
75-
with:
76-
# Use the ref from the changelog update to include the updated changelog.
77-
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}
7886
secrets: inherit

.github/workflows/manual_release_docs.yaml

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ on:
66

77
# Runs when invoked by another workflow.
88
workflow_call:
9-
inputs:
10-
ref:
11-
description: Git ref to checkout.
12-
required: true
13-
type: string
149

1510
permissions:
1611
contents: read
@@ -35,7 +30,6 @@ jobs:
3530
uses: actions/checkout@v6
3631
with:
3732
token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
38-
ref: ${{ inputs.ref || github.event.repository.default_branch }}
3933

4034
- name: Set up Node
4135
uses: actions/setup-node@v6
@@ -56,22 +50,20 @@ jobs:
5650
run: uv run poe install-dev
5751

5852
- name: Install pnpm and website dependencies
59-
uses: apify/workflows/pnpm-install@main
53+
uses: apify/actions/pnpm-install@v1.1.2
6054
with:
6155
working-directory: website
6256

6357
- name: Update docs theme
6458
run: uv run poe update-docs-theme
6559

6660
- name: Commit the updated package.json and lockfile
67-
uses: EndBug/add-and-commit@v10
61+
uses: apify/actions/signed-commit@v1.0.0
6862
with:
69-
add: website/package.json website/pnpm-lock.yaml
7063
message: "chore: Automatic docs theme update [skip ci]"
71-
default_author: github_actions
64+
add: 'website/package.json website/pnpm-lock.yaml'
7265
pull: '--rebase --autostash'
73-
# `actions/checkout` detaches HEAD on SHA refs; EndBug needs a branch to push.
74-
new_branch: ${{ github.event.repository.default_branch }}
66+
github-token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
7567

7668
- name: Build docs
7769
run: uv run poe build-docs

.github/workflows/manual_release_stable.yaml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
changelog: ${{ steps.release_prepare.outputs.changelog }}
4444
release_notes: ${{ steps.release_prepare.outputs.release_notes }}
4545
steps:
46-
- uses: apify/workflows/git-cliff-release@main
46+
- uses: apify/actions/git-cliff-release@v1.1.2
4747
name: Release prepare
4848
id: release_prepare
4949
with:
@@ -91,13 +91,24 @@ jobs:
9191
url: https://pypi.org/project/apify
9292
steps:
9393
- name: Prepare distribution
94-
uses: apify/workflows/prepare-pypi-distribution@main
94+
uses: apify/actions/prepare-pypi-distribution@v1.1.2
9595
with:
9696
package_name: apify
9797
is_prerelease: ""
9898
version_number: ${{ needs.release_prepare.outputs.version_number }}
9999
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}
100100

101+
- name: Verify built package
102+
uses: apify/actions/python-package-check@v1.1.0
103+
with:
104+
package_name: apify
105+
dist_dir: dist
106+
python_version: "3.14"
107+
smoke_code: |
108+
from apify import Actor, Configuration, ProxyConfiguration
109+
Configuration()
110+
ProxyConfiguration()
111+
101112
# Publish the package to PyPI using PyPA official GitHub action with OIDC authentication.
102113
- name: Publish package to PyPI
103114
uses: pypa/gh-action-pypi-publish@release/v1
@@ -108,9 +119,6 @@ jobs:
108119
permissions:
109120
contents: write
110121
uses: ./.github/workflows/manual_version_docs.yaml
111-
with:
112-
# Commit the version docs changes on top of the changelog commit.
113-
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}
114122
secrets: inherit
115123

116124
doc_release:
@@ -121,9 +129,6 @@ jobs:
121129
pages: write
122130
id-token: write
123131
uses: ./.github/workflows/manual_release_docs.yaml
124-
with:
125-
# Commit the docs release changes on top of the version docs commit.
126-
ref: ${{ needs.version_docs.outputs.version_docs_commitish }}
127132
secrets: inherit
128133

129134
trigger_docker_build:

.github/workflows/manual_version_docs.yaml

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ on:
66

77
# Runs when invoked by another workflow.
88
workflow_call:
9-
inputs:
10-
ref:
11-
description: Git ref to checkout.
12-
required: true
13-
type: string
14-
outputs:
15-
version_docs_commitish:
16-
description: The commit SHA of the versioned docs commit.
17-
value: ${{ jobs.version_docs.outputs.version_docs_commitish }}
189

1910
concurrency:
2011
group: version-docs
@@ -31,8 +22,6 @@ jobs:
3122
version_docs:
3223
name: Version docs
3324
runs-on: ubuntu-latest
34-
outputs:
35-
version_docs_commitish: ${{ steps.resolve_commitish.outputs.commitish }}
3625
permissions:
3726
contents: write
3827

@@ -41,21 +30,10 @@ jobs:
4130
working-directory: website
4231

4332
steps:
44-
- name: Determine checkout ref
45-
id: resolve_ref
46-
working-directory: .
47-
env:
48-
INPUT_REF: ${{ inputs.ref }}
49-
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
50-
run: |
51-
REF="${INPUT_REF:-$DEFAULT_BRANCH}"
52-
echo "ref=$REF" >> "$GITHUB_OUTPUT"
53-
5433
- name: Checkout repository
5534
uses: actions/checkout@v6
5635
with:
5736
token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
58-
ref: ${{ inputs.ref || github.event.repository.default_branch }}
5937

6038
- name: Set up Node
6139
uses: actions/setup-node@v6
@@ -77,7 +55,7 @@ jobs:
7755
working-directory: .
7856

7957
- name: Install pnpm and website dependencies
80-
uses: apify/workflows/pnpm-install@main
58+
uses: apify/actions/pnpm-install@v1.1.2
8159
with:
8260
working-directory: website
8361

@@ -118,19 +96,9 @@ jobs:
11896
pnpm exec docusaurus api:version "$MAJOR_MINOR_VERSION"
11997
12098
- name: Commit and push versioned docs
121-
id: commit_versioned_docs
122-
uses: EndBug/add-and-commit@v10
99+
uses: apify/actions/signed-commit@v1.0.0
123100
with:
124-
add: website/versioned_docs website/versioned_sidebars website/versions.json
125101
message: "docs: Version docs for v${{ steps.snapshot.outputs.version }} [skip ci]"
126-
default_author: github_actions
127-
# `actions/checkout` detaches HEAD on SHA refs; EndBug needs a branch to push.
128-
new_branch: ${{ github.event.repository.default_branch }}
102+
add: 'website/versioned_docs website/versioned_sidebars website/versions.json'
129103
pull: '--rebase --autostash'
130-
131-
- name: Resolve output commitish
132-
id: resolve_commitish
133-
env:
134-
COMMIT_SHA: ${{ steps.commit_versioned_docs.outputs.commit_long_sha }}
135-
run: |
136-
echo "commitish=${COMMIT_SHA:-$(git rev-parse HEAD)}" >> "$GITHUB_OUTPUT"
104+
github-token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}

.github/workflows/on_master.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ jobs:
2525
pages: write
2626
id-token: write
2727
uses: ./.github/workflows/manual_release_docs.yaml
28-
with:
29-
# Use the same ref as the one that triggered the workflow.
30-
ref: ${{ github.ref }}
3128
secrets: inherit
3229

3330
code_checks:
@@ -59,6 +56,6 @@ jobs:
5956
actions: write # Required by execute-workflow.
6057
steps:
6158
- name: Dispatch beta release workflow
62-
uses: apify/workflows/execute-workflow@main
59+
uses: apify/actions/execute-workflow@v1.1.2
6360
with:
6461
workflow: manual_release_beta.yaml

.github/workflows/on_pull_request.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ jobs:
2525
name: Code checks
2626
uses: ./.github/workflows/_check_code.yaml
2727

28+
package_check:
29+
name: Package check
30+
uses: ./.github/workflows/_check_package.yaml
31+
2832
tests:
2933
name: Tests
3034
uses: ./.github/workflows/_tests.yaml

docs/02_concepts/01_actor_lifecycle.mdx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ description: How an Apify Actor starts, runs, and shuts down, including context
77
import RunnableCodeBlock from '@site/src/components/RunnableCodeBlock';
88
import Tabs from '@theme/Tabs';
99
import TabItem from '@theme/TabItem';
10+
import ApiLink from '@theme/ApiLink';
1011

1112
import ClassContextExample from '!!raw-loader!roa-loader!./code/01_class_context.py';
1213
import ClassManualExample from '!!raw-loader!roa-loader!./code/01_class_manual.py';
@@ -26,7 +27,7 @@ This guide explains how an **Apify Actor** starts, runs, and shuts down, describ
2627

2728
During initialization, the SDK prepares all the components required to integrate with the Apify platform. It loads configuration from environment variables, initializes access to platform storages such as the [key-value store, dataset, and request queue](https://docs.apify.com/platform/storage), sets up event handling for [platform events](https://docs.apify.com/platform/integrations/webhooks/events), and configures logging.
2829

29-
The recommended approach in Python is to use the global [`Actor`](https://docs.apify.com/sdk/python/reference/class/Actor) class as an asynchronous context manager. This approach automatically manages setup and teardown and keeps your code concise. When entering the context, the SDK loads configuration and initializes clients lazily—for example, a dataset is opened only when it is first accessed. If the Actor runs on the Apify platform, it also begins listening for platform events.
30+
The recommended approach in Python is to use the global <ApiLink to="class/Actor">`Actor`</ApiLink> class as an asynchronous context manager. This approach automatically manages setup and teardown and keeps your code concise. When entering the context, the SDK loads configuration and initializes clients lazily—for example, a dataset is opened only when it is first accessed. If the Actor runs on the Apify platform, it also begins listening for platform events.
3031

3132
When the Actor exits, either normally or due to an exception, the SDK performs a graceful shutdown. It persists the final Actor state, stops event handling, and sets the terminal exit code together with the [status message](https://docs.apify.com/platform/actors/development/programming-interface/status-messages).
3233

@@ -43,9 +44,9 @@ When the Actor exits, either normally or due to an exception, the SDK performs a
4344
</TabItem>
4445
</Tabs>
4546

46-
You can also create an [`Actor`](https://docs.apify.com/sdk/python/reference/class/Actor) instance directly. This does not change its capabilities but allows you to specify optional parameters during initialization. The key parameters are:
47+
You can also create an <ApiLink to="class/Actor">`Actor`</ApiLink> instance directly. This does not change its capabilities but allows you to specify optional parameters during initialization. The key parameters are:
4748

48-
- `configuration` — a custom [`Configuration`](https://docs.apify.com/sdk/python/reference/class/Configuration) instance to control storage paths, API URLs, and other settings.
49+
- `configuration` — a custom <ApiLink to="class/Configuration">`Configuration`</ApiLink> instance to control storage paths, API URLs, and other settings.
4950
- `configure_logging` — whether to set up default logging configuration (default `True`). Set to `False` if you configure logging yourself.
5051
- `exit_process` — whether the Actor calls `sys.exit()` when the context manager exits. Defaults to `True`, except in IPython, Pytest, and Scrapy environments.
5152
- `event_listeners_timeout` — maximum time to wait for Actor event listeners to complete before exiting.
@@ -72,18 +73,18 @@ Good error handling lets your Actor fail fast on critical errors, retry transien
7273

7374
The SDK provides helper methods for explicit control:
7475

75-
- [`Actor.exit`](https://docs.apify.com/sdk/python/reference/class/Actor#exit) - terminates the run successfully (default exit code 0).
76-
- [`Actor.fail`](https://docs.apify.com/sdk/python/reference/class/Actor#fail) - marks the run as failed (default exit code 1).
76+
- <ApiLink to="class/Actor#exit">`Actor.exit`</ApiLink> - terminates the run successfully (default exit code 0).
77+
- <ApiLink to="class/Actor#fail">`Actor.fail`</ApiLink> - marks the run as failed (default exit code 1).
7778

7879
Any non-zero exit code is treated as a `FAILED` run. You rarely need to call these methods directly unless you want to perform a controlled shutdown or customize the exit behavior.
7980

80-
Catch exceptions only when necessary - for example, to retry network timeouts or map specific errors to exit codes. Keep retry loops bounded with backoff and re-raise once exhausted. Make your processing idempotent so that restarts don't corrupt results. Both [`Actor.exit`](https://docs.apify.com/sdk/python/reference/class/Actor#exit) and [`Actor.fail`](https://docs.apify.com/sdk/python/reference/class/Actor#fail) perform the same cleanup, so complete any long-running persistence before calling them.
81+
Catch exceptions only when necessary - for example, to retry network timeouts or map specific errors to exit codes. Keep retry loops bounded with backoff and re-raise once exhausted. Make your processing idempotent so that restarts don't corrupt results. Both <ApiLink to="class/Actor#exit">`Actor.exit`</ApiLink> and <ApiLink to="class/Actor#fail">`Actor.fail`</ApiLink> perform the same cleanup, so complete any long-running persistence before calling them.
8182

8283
Below is a minimal context-manager example where an unhandled exception automatically fails the run, followed by a manual pattern giving you more control.
8384

8485
<RunnableCodeBlock className="language-python" language="python">{ErrorHandlingContextExample}</RunnableCodeBlock>
8586

86-
If you need explicit control over exit codes or status messages, you can manage the Actor manually using [`Actor.init`](https://docs.apify.com/sdk/python/reference/class/Actor#init), [`Actor.exit`](https://docs.apify.com/sdk/python/reference/class/Actor#exit), and [`Actor.fail`](https://docs.apify.com/sdk/python/reference/class/Actor#fail).
87+
If you need explicit control over exit codes or status messages, you can manage the Actor manually using <ApiLink to="class/Actor#init">`Actor.init`</ApiLink>, <ApiLink to="class/Actor#exit">`Actor.exit`</ApiLink>, and <ApiLink to="class/Actor#fail">`Actor.fail`</ApiLink>.
8788

8889
<RunnableCodeBlock className="language-python" language="python">{ErrorHandlingManualExample}</RunnableCodeBlock>
8990

@@ -105,4 +106,4 @@ Update the status only when the user's understanding of progress changes - avoid
105106

106107
## Conclusion
107108

108-
This page has presented the full Actor lifecycle: initialization, execution, error handling, rebooting, shutdown and status messages. You've seen how the SDK supports both context-based and manual control patterns. For deeper dives, explore the [reference docs](https://docs.apify.com/sdk/python/reference), [guides](https://docs.apify.com/sdk/python/docs/guides/beautifulsoup-httpx), and [platform documentation](https://docs.apify.com/platform).
109+
This page has presented the full Actor lifecycle: initialization, execution, error handling, rebooting, shutdown and status messages. You've seen how the SDK supports both context-based and manual control patterns. For deeper dives, explore the <ApiLink to="">reference docs</ApiLink>, [guides](https://docs.apify.com/sdk/python/docs/guides/beautifulsoup-httpx), and [platform documentation](https://docs.apify.com/platform).

docs/02_concepts/02_actor_input.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import RunnableCodeBlock from '@site/src/components/RunnableCodeBlock';
88

99
import InputExample from '!!raw-loader!roa-loader!./code/02_input.py';
1010
import RequestListExample from '!!raw-loader!roa-loader!./code/02_request_list.py';
11-
import ApiLink from '@site/src/components/ApiLink';
11+
import ApiLink from '@theme/ApiLink';
1212

1313
The Actor gets its [input](https://docs.apify.com/platform/actors/running/input) from the input record in its default [key-value store](https://docs.apify.com/platform/storage/key-value-store).
1414

docs/02_concepts/03_storages.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import RunnableCodeBlock from '@site/src/components/RunnableCodeBlock';
88

99
import OpeningStoragesExample from '!!raw-loader!roa-loader!./code/03_opening_storages.py';
1010
import OpeningStoragesAliasExample from '!!raw-loader!roa-loader!./code/03_opening_storages_alias.py';
11-
import ApiLink from '@site/src/components/ApiLink';
11+
import ApiLink from '@theme/ApiLink';
1212
import DeletingStoragesExample from '!!raw-loader!roa-loader!./code/03_deleting_storages.py';
1313
import DatasetReadWriteExample from '!!raw-loader!roa-loader!./code/03_dataset_read_write.py';
1414
import DatasetExportsExample from '!!raw-loader!roa-loader!./code/03_dataset_exports.py';

0 commit comments

Comments
 (0)