Skip to main content

An asynchronous version of pychasing (a wrapper for the https://ballchasing.com API).

Install

pip install async-pychasing

Usage

This asynchronous wrapper functions similarly to pychasing; it is recommended that you read the documentation as it explains the core functionality. Additionally, all helper enumerations and types are used from the pychasing module, and are not included with async-pychasing. There are two main changes in the way this version should be used. Creating a Client is the same (although async_pychasing is used instead of pychasing):

import async_pychasing
import pychasing

pychasing_client = async_pychasing.Client(
    token="your_token",
    auto_rate_limit=True,
    patreon_tier=pychasing.PatreonTier.none
)

but the way you interact with the client is slightly different; instead of calling methods directly from the Client instance, an aiohttp.ClientSession instance must be passed into the Client, which will then return a async_pychasing.Session instance. This Session instance is then how you interact with the API, and contains all the usual methods (although asynchronous). For example:

import aiohttp
import asyncio

# keep in mind that a new aiohttp.ClientSession is being created simply for illustration. In reality, you should NOT create a new aiohttp.ClientSession for each individual request.
async def main() -> None:
    async with aiohttp.ClientSession() as cs:
        async with pychasing_client(cs) as bs: # or pychasing_client.session(cs)
            await bs.get_replay(...)

if __name__ == "__main__":
    asyncio.run(main())

Because we're using aiohttp instead of requests, the way we download replays through the download_replays method is slightly different (we use <response>.content.iter_chunked(...) instead of <response>.iter_content(...)):

async def download_replay(bs: async_pychasing.Session, replay_id: str) -> None:
    async with bs.download_replay(replay_id) as replay:
        with open("my_replay.replay", "wb") as outfile: # or using an async file manager
            async for chunk in replay.content.iter_chunks(4096):
                outfile.write(chunk)

Notes on rate limiting

By default (if rate limiting is enabled) the methods are rate limited similarly to pychasing, in which one function call waits until the previous call has completed. For faster call speeds, this can be avoided by using the concurrent and ca_deviation options upon Client instantiation, although there are some drawbacks. The main drawback is that there is a posibility for getting rate-limited by the API, whereas with concurrent=False that is not the case. If concurrent=True, the methods will be rate limited without consideration for execution time of the HTTP[s] request. To help account for this time, you can set ca_deviation to a float; this will cause each function to take <ca_deviation> seconds longer before allowing the next function call to go through, which can allow for some extra leeway with request speed variation. To optimize speed, you should try to separate your API calls from your processing. For example (listing 10 replays, then getting the GUID of each replay):

import async_pychasing
import pychasing
import aiohttp
import asyncio

client = async_pychasing.Client(...)

async def get_guids(guids: list[str],
                    responses: asyncio.Queue[aiohttp.ClientResponse],
                    break_after: int) -> None:
    for i in range(break_after):
        r = await responses.get()
        j = await r.json()
        guids.append(j["match_guid"])


# ONLY getting the replay and putting it into the queue
async def fetch_replay(bs: async_pychasing.Session, id: str,
                       responses: asyncio.Queue[aiohttp.ClientResponse]
                       ) -> None:
    res = await bs.get_replay(id)
    await responses.put(res)


async def main(guids: list[str],
               responses: asyncio.Queue[aiohttp.ClientResponse]) -> None:
    async with aiohttp.ClientSession() as client_session:
        async with client(client_session) as ballchasing_session:
            replay_list = await bs.list_replays(count=10)
            replay_list_json = await replay_list.json()
            replay_ids = [r["id"] for r in replay_list_json["list"]]

            loop = asyncio.get_event_loop()
            tasks: list[asyncio.Task] = []
            for id in replay_ids:
                tasks.append(loop.create_task(fetch_replay(ballchasing_session,
                                                           id,
                                                           responses)))
            tasks.append(loop.create_task(get_guids(guids,
                                                    responses,
                                                    len(replay_ids))))

            await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main([], asyncio.Queue()))

Metadata

Release files for async-pychasing 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for async-pychasing 0.0.1
File Size Uploaded Provenance Actions
async-pychasing-0.0.1.tar.gz 11.8 kB Without provenance Details for async-pychasing-0.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for async-pychasing 0.0.1
File Interpreter ABI Platform Actions
async_pychasing-0.0.1-py3-none-any.whl Python 3 none any Details for async_pychasing-0.0.1-py3-none-any.whl

Total release size: 22.8 kB

Release files / async-pychasing-0.0.1.tar.gz

Download URL async-pychasing-0.0.1.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ac19eaacf85a40cf2c6ba38f6f3bfe80307bac0715320ad2d5659746a662e243
BLAKE2b-256 checksum
How to use checksums
8d1ce80ecc0443dce31ce73c094ef89395ba431cc87e02c5b09a3d429aba06c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.1

Release files / async_pychasing-0.0.1-py3-none-any.whl

Download URL async_pychasing-0.0.1-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
69fa2d27b557ecd8f82fed1df9f3a7edb8a2e308ea136c58dd0d679f1a71c0ce
BLAKE2b-256 checksum
How to use checksums
cd8e46ba53273a709b238aa492e9c4098d3aa48e7c529b1c371493e92fc54dc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.1

Security for async-pychasing 0.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page