Skip to content

Commit

Permalink
Update dependencies, sync project setup with Apify SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
fnesveda committed May 23, 2023
1 parent ffa2984 commit e8a84af
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 49 deletions.
1 change: 0 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,3 @@ jobs:
run: gh release upload ${{ github.ref_name }} dist/*
env:
GH_TOKEN: ${{ github.token }}

6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
Changelog
=========

[1.2.0](../../releases/tag/v1.2.0) - Unreleased
[1.2.0](../../releases/tag/v1.2.0) - 2023-05-23

### Added

- added option to change the build, memory limit and timeout when resurrecting a run

### Internal changes

- updated dependencies

[1.1.1](../../releases/tag/v1.1.1) - 2023-05-05

### Internal changes
Expand Down
54 changes: 54 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Development

## Environment

For local development, it is required to have Python 3.8 installed.

It is recommended to set up a virtual environment while developing this package to isolate your development environment,
however, due to the many varied ways Python can be installed and virtual environments can be set up,
this is left up to the developers to do themselves.

One recommended way is with the built-in `venv` module:

```bash
python3 -m venv .venv
source .venv/bin/activate
```

To improve on the experience, you can use [pyenv](https://github.com/pyenv/pyenv) to have an environment with a pinned Python version,
and [direnv](https://github.com/direnv/direnv) to automatically activate/deactivate the environment when you enter/exit the project folder.

## Dependencies

To install this package and its development dependencies, run `make install-dev`

## Formatting

We use `autopep8` and `isort` to automatically format the code to a common format. To run the formatting, just run `make format`.

## Linting, type-checking and unit testing

We use `flake8` for linting, `mypy` for type checking and `pytest` for unit testing. To run these tools, just run `make check-code`.

## Documentation

We use the [Google docstring format](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) for documenting the code.
We document every user-facing class or method, and enforce that using the flake8-docstrings library.

The documentation is then rendered from the docstrings in the code, using `pydoc-markdown` and some heavy post-processing,
and from Markdown documents in the `docs` folder in the `docs` branch, and then rendered using Docusaurus and published to GitHub pages.

## Release process

Publishing new versions to [PyPI](https://pypi.org/project/apify-client) happens automatically through GitHub Actions.

On each commit to the `master` branch, a new beta release is published, taking the version number from `pyproject.toml`
and automatically incrementing the beta version suffix by 1 from the last beta release published to PyPI.

A stable version is published when a new release is created using GitHub Releases, again taking the version number from `pyproject.toml`.
The built package assets are automatically uploaded to the GitHub release.

If there is already a stable version with the same version number as in `pyproject.toml` published to PyPI, the publish process fails,
so don't forget to update the version number before releasing a new version.
The release process also fails when the released version is not described in `CHANGELOG.md`,
so don't forget to describe the changes in the new version there.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: clean install-dev lint unit-tests integration-tests type-check check-code format docs check-docs check-async-docstrings fix-async-docstrings check-changelog-entry
.PHONY: clean install-dev build publish twine-check lint unit-tests integration-tests type-check check-code format docs check-docs check-async-docstrings fix-async-docstrings check-changelog-entry

# This is default for local testing, but GitHub workflows override it to a higher value in CI
INTEGRATION_TESTS_CONCURRENCY = 1
Expand Down
67 changes: 29 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,56 +17,47 @@ To do that, simply run `pip install apify-client` in your terminal.

For usage instructions, check the documentation on [Apify Docs](https://docs.apify.com/api/client/python/) or in [`docs/docs.md`](docs/docs.md).

## Development
## Quick Start

### Environment
```python
from apify_client import ApifyClient

For local development, it is required to have Python 3.8 installed.
apify_client = ApifyClient('MY-APIFY-TOKEN')

It is recommended to set up a virtual environment while developing this package to isolate your development environment,
however, due to the many varied ways Python can be installed and virtual environments can be set up,
this is left up to the developers to do themselves.
# Start an actor and wait for it to finish
actor_call = apify_client.actor('john-doe/my-cool-actor').call()

One recommended way is with the built-in `venv` module:

```bash
python3 -m venv .venv
source .venv/bin/activate
# Fetch results from the actor's default dataset
dataset_items = apify_client.dataset(actor_call['defaultDatasetId']).list_items().items
```

To improve on the experience, you can use [pyenv](https://github.com/pyenv/pyenv) to have an environment with a pinned Python version,
and [direnv](https://github.com/direnv/direnv) to automatically activate/deactivate the environment when you enter/exit the project folder.

### Dependencies

To install this package and its development dependencies, run `make install-dev`

### Formatting

We use `autopep8` and `isort` to automatically format the code to a common format. To run the formatting, just run `make format`.

### Linting, type-checking and unit testing
## Features

We use `flake8` for linting, `mypy` for type checking and `pytest` for unit testing. To run these tools, just run `make check-code`.
Besides greatly simplifying the process of querying the Apify API, the client provides other useful features.

### Documentation
### Automatic parsing and error handling

We use the [Google docstring format](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) for documenting the code.
We document every user-facing class or method, and enforce that using the flake8-docstrings library.
Based on the endpoint, the client automatically extracts the relevant data and returns it in the
expected format. Date strings are automatically converted to `datetime.datetime` objects. For exceptions,
we throw an `ApifyApiError`, which wraps the plain JSON errors returned by API and enriches
them with other context for easier debugging.

The documentation is then rendered from the docstrings in the code using Sphinx and some heavy post-processing and saved as `docs/docs.md`.
To generate the documentation, just run `make docs`.
### Retries with exponential backoff

### Release process
Network communication sometimes fails. The client will automatically retry requests that
failed due to a network error, an internal error of the Apify API (HTTP 500+) or rate limit error (HTTP 429).
By default, it will retry up to 8 times. First retry will be attempted after ~500ms, second after ~1000ms
and so on. You can configure those parameters using the `max_retries` and `min_delay_between_retries_millis`
options of the `ApifyClient` constructor.

Publishing new versions to [PyPI](https://pypi.org/project/apify-client) happens automatically through GitHub Actions.
### Support for asynchronous usage

On each commit to the `master` branch, a new beta release is published, taking the version number from `pyproject.toml`
and automatically incrementing the beta version suffix by 1 from the last beta release published to PyPI.
Starting with version 1.0.0, the package offers an asynchronous version of the client, [`ApifyClientAsync`](https://docs.apify.com/api/client/python),
which allows you to work with the Apify API in an asynchronous way, using the standard `async`/`await` syntax.

A stable version is published when a new release is created using GitHub Releases, again taking the version number from `pyproject.toml`. The built package assets are automatically uploaded to the GitHub release.
### Convenience functions and options

If there is already a stable version with the same version number as in `pyproject.toml` published to PyPI, the publish process fails,
so don't forget to update the version number before releasing a new version.
The release process also fails when the released version is not described in `CHANGELOG.md`,
so don't forget to describe the changes in the new version there.
Some actions can't be performed by the API itself, such as indefinite waiting for an actor run to finish
(because of network timeouts). The client provides convenient `call()` and `wait_for_finish()` functions that do that.
Key-value store records can be retrieved as objects, buffers or streams via the respective options, dataset items
can be fetched as individual objects or serialized data and we plan to add better stream support and async iterators.
11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ classifiers = [

requires-python = ">=3.8"
dependencies = [
"httpx ~= 0.23.0"
"httpx ~= 0.24.1"
]

[project.optional-dependencies]
dev = [
"autopep8 ~= 2.0.2",
"build ~= 0.10.0",
"flake8 ~= 6.0.0",
"flake8-bugbear ~= 23.3.23",
"flake8-bugbear ~= 23.5.9",
"flake8-commas ~= 2.1.0",
"flake8-comprehensions ~= 3.12.0",
"flake8-datetimez ~= 20.10.0",
Expand All @@ -42,15 +42,15 @@ dev = [
"flake8-quotes ~= 3.3.2",
"flake8-unused-arguments ~= 0.0.13",
"isort ~= 5.12.0",
"mypy ~= 1.2.0",
"mypy ~= 1.3.0",
"pep8-naming ~= 0.13.3",
"pre-commit ~= 3.3.1",
"pre-commit ~= 3.3.2",
"pytest ~= 7.3.1",
"pytest-asyncio ~= 0.21.0",
"pytest-only ~= 2.0.0",
"pytest-randomly ~= 3.12.0",
"pytest-timeout ~= 2.1.0",
"pytest-xdist ~= 3.2.1",
"pytest-xdist ~= 3.3.1",
"redbaron ~= 0.9.2",
"sphinx ~= 6.1.3",
"sphinx-autodoc-typehints ~= 1.22",
Expand All @@ -63,6 +63,7 @@ dev = [
"Documentation" = "https://docs.apify.com/api/client/python/"
"Source" = "https://github.com/apify/apify-client-python"
"Issue tracker" = "https://github.com/apify/apify-client-python/issues"
"Changelog" = "https://github.com/apify/apify-client-python/blob/master/CHANGELOG.md"
"Apify Homepage" = "https://apify.com"

[build-system]
Expand Down
2 changes: 1 addition & 1 deletion scripts/check_version_in_changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
if not CHANGELOG_PATH.is_file():
raise RuntimeError('Unable to find CHANGELOG.md file')

with open(CHANGELOG_PATH) as changelog_file:
with open(CHANGELOG_PATH, encoding='utf-8') as changelog_file:
for line in changelog_file:
# The heading for the changelog entry for the given version can start with either the version number, or the version number in a link
if re.match(fr'\[?{current_package_version}([\] ]|$)', line):
Expand Down
4 changes: 2 additions & 2 deletions scripts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Load the current version number from pyproject.toml
# It is on a line in the format `version = "1.2.3"`
def get_current_package_version() -> str:
with open(PYPROJECT_TOML_FILE_PATH, 'r') as pyproject_toml_file:
with open(PYPROJECT_TOML_FILE_PATH, 'r', encoding='utf-8') as pyproject_toml_file:
for line in pyproject_toml_file:
if line.startswith('version = '):
delim = '"' if '"' in line else "'"
Expand All @@ -22,7 +22,7 @@ def get_current_package_version() -> str:
# Write the given version number from pyproject.toml
# It replaces the version number on the line with the format `version = "1.2.3"`
def set_current_package_version(version: str) -> None:
with open(PYPROJECT_TOML_FILE_PATH, 'r+') as pyproject_toml_file:
with open(PYPROJECT_TOML_FILE_PATH, 'r+', encoding='utf-8') as pyproject_toml_file:
updated_pyproject_toml_file_lines = []
version_string_found = False
for line in pyproject_toml_file:
Expand Down

0 comments on commit e8a84af

Please sign in to comment.