aiobungie

A statically typed, asynchronous API wrapper for building clients for Bungie's API in Python.

Getting Started

aiobungie provides 3 different client interfaces to get started with, each serve a different purpose.

  • Client: is probably what you want to get started with first. It provides minimal abstraction for the REST api. Is Pythonic.
  • RESTClient: When you're building a light-weight REST backend. You can use this one. It returns JSON objects instead of dataclasses, as well OAuth2 API. This is considered lower-level version of Client.
  • RESTPool: when you're serving a large amount of users and want to spawn a session for each. each instance of this pool returns a RESTClient.

Check either the examples or each of those objects's documentation for more information about the usage.

 1# MIT License
 2# ruff: noqa: F401
 3# ruff: noqa: F403
 4# ruff: noqa: F405
 5# Copyright (c) 2020 - Present nxtlo
 6#
 7# Permission is hereby granted, free of charge, to any person obtaining a copy
 8# of this software and associated documentation files (the "Software"), to deal
 9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in all
15# copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23# SOFTWARE.
24
25"""A statically typed, asynchronous API wrapper for building clients for Bungie's API in Python.
26
27### Getting Started
28
29aiobungie provides 3 different client interfaces to get started with, each serve a different purpose.
30
31* `Client`: is probably what you want to get started with first. It provides minimal abstraction for the REST api. Is [Pythonic](https://stackoverflow.com/questions/84102/what-is-idiomatic-code#84270).
32* `RESTClient`: When you're building a light-weight REST backend. You can use this one. It returns `JSON` objects instead of `dataclasses`, as well `OAuth2` API.
33This is considered lower-level version of `Client`.
34* `RESTPool`: when you're serving a large amount of users and want to spawn a session for each. each instance of this pool returns a `RESTClient`.
35
36Check either the examples or each of those objects's documentation for more information about the usage.
37"""
38
39from __future__ import annotations
40
41from aiobungie import api, builders, crates, framework, traits, typedefs, url
42from aiobungie.client import Client
43from aiobungie.error import *
44from aiobungie.internal.enums import *
45from aiobungie.rest import *
46
47# Activity enums
48from .crates.activity import Difficulty
49
50# Clans enums
51from .crates.clans import GroupDate
52
53# Components enums
54from .crates.components import ComponentPrivacy
55
56# Entity enums
57from .crates.entity import GatingScope, ObjectiveUIStyle, ValueUIStyle
58
59# Fireteam enums.
60from .crates.fireteams import (
61    FireteamActivity,
62    FireteamDate,
63    FireteamLanguage,
64    FireteamPlatform,
65)
66
67# Records enums
68from .crates.records import RecordState
69
70# Package metadata
71from .metadata import (
72    __about__,
73    __author__,
74    __docs__,
75    __email__,
76    __license__,
77    __url__,
78    __version__,
79)
80
81__all__ = [mod for mod in dir() if not mod.startswith("_")]  # type: ignore
@attrs.define(auto_exc=True)
class AiobungieError(builtins.RuntimeError):
78@attrs.define(auto_exc=True)
79class AiobungieError(RuntimeError):
80    """Base class that all other exceptions inherit from."""

Base class that all other exceptions inherit from.

AiobungieError()
17def __init__(self, ):
18    BaseException.__init__(self, )

Method generated by attrs for class AiobungieError.

@typing.final
class AmmoType(builtins.int, aiobungie.Enum):
638@typing.final
639class AmmoType(int, Enum):
640    """AN enum for Detyiny 2 ammo types."""
641
642    NONE = 0
643    PRIMARY = 1
644    SPECIAL = 2
645    HEAVY = 3

AN enum for Detyiny 2 ammo types.

NONE = <AmmoType.NONE: 0>
PRIMARY = <AmmoType.PRIMARY: 1>
SPECIAL = <AmmoType.SPECIAL: 2>
HEAVY = <AmmoType.HEAVY: 3>
Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class BadRequest(aiobungie.HTTPError):
171@attrs.define(auto_exc=True)
172class BadRequest(HTTPError):
173    """An exception raised when requesting a resource with the provided data is wrong."""
174
175    url: typedefs.StrOrURL | None
176    """The URL/endpoint caused this error."""
177
178    body: typing.Any
179    """The response body."""
180
181    headers: multidict.CIMultiDictProxy[str]
182    """The response headers."""
183
184    http_status: http.HTTPStatus = attrs.field(
185        default=http.HTTPStatus.BAD_REQUEST, init=False
186    )

An exception raised when requesting a resource with the provided data is wrong.

BadRequest( message: 'str', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]')
17def __init__(self, message, url, body, headers):
18    self.message = message
19    self.url = url
20    self.body = body
21    self.headers = headers
22    self.http_status = attr_dict['http_status'].default
23    BaseException.__init__(self, self.message,self.url,self.body,self.headers)

Method generated by attrs for class BadRequest.

url: 'typedefs.StrOrURL | None'

The URL/endpoint caused this error.

body: 'typing.Any'

The response body.

headers: 'multidict.CIMultiDictProxy[str]'

The response headers.

http_status: 'http.HTTPStatus'

The response status.

Inherited Members
HTTPError
message
@typing.final
class ClanMemberType(builtins.int, aiobungie.Enum):
693@typing.final
694class ClanMemberType(int, Enum):
695    """An enum for bungie clan member types."""
696
697    NONE = 0
698    BEGINNER = 1
699    MEMBER = 2
700    ADMIN = 3
701    ACTING_FOUNDER = 4
702    FOUNDER = 5

An enum for bungie clan member types.

NONE = <ClanMemberType.NONE: 0>
BEGINNER = <ClanMemberType.BEGINNER: 1>
MEMBER = <ClanMemberType.MEMBER: 2>
ADMIN = <ClanMemberType.ADMIN: 3>
ACTING_FOUNDER = <ClanMemberType.ACTING_FOUNDER: 4>
FOUNDER = <ClanMemberType.FOUNDER: 5>
Inherited Members
Enum
name
value
@typing.final
class Class(builtins.int, aiobungie.Enum):
469@typing.final
470class Class(int, Enum):
471    """An Enum for Destiny character classes."""
472
473    TITAN = 0
474    HUNTER = 1
475    WARLOCK = 2
476    UNKNOWN = 3

An Enum for Destiny character classes.

TITAN = <Class.TITAN: 0>
HUNTER = <Class.HUNTER: 1>
WARLOCK = <Class.WARLOCK: 2>
UNKNOWN = <Class.UNKNOWN: 3>
Inherited Members
Enum
name
value
class Client(aiobungie.traits.Compact):
  56class Client(traits.Compact):
  57    """Compact standard client implementation.
  58
  59    This client is the way to be able to start sending requests over the REST API and receiving deserialized response objects.
  60
  61    Refer to `aiobungie.RESTClient` if you prefer to use a more lower-level client.
  62
  63    Example
  64    -------
  65    ```py
  66    import aiobungie
  67    import asyncio
  68
  69    async def main():
  70        client = aiobungie.Client('token')
  71        async with client.rest:
  72            user = await client.fetch_bungie_user(20315338)
  73            print(user)
  74
  75    asyncio.run(main())
  76    ```
  77
  78    Parameters
  79    -----------
  80    token: `str`
  81        Your Bungie's API key or Token from the developer's portal.
  82
  83    Other Parameters
  84    ----------------
  85    client_secret : `str | None`
  86        An optional application client secret,
  87        This is only needed if you're fetching OAuth2 tokens with this client.
  88    client_id : `int | None`
  89        An optional application client id,
  90        This is only needed if you're fetching OAuth2 tokens with this client.
  91    settings: `aiobungie.builders.Settings | None`
  92        The client settings to use, if `None` the default will be used.
  93    max_retries : `int`
  94        The max retries number to retry if the request hit a `5xx` status code.
  95    debug: `"TRACE" | bool | int`
  96        The level of logging to enable.
  97    """
  98
  99    __slots__ = ("_rest", "_framework")
 100
 101    def __init__(
 102        self,
 103        token: str,
 104        /,
 105        *,
 106        client_secret: str | None = None,
 107        client_id: int | None = None,
 108        settings: builders.Settings | None = None,
 109        max_retries: int = 4,
 110        debug: typing.Literal["TRACE"] | bool | int = False,
 111    ) -> None:
 112        self._rest = rest_.RESTClient(
 113            token,
 114            client_secret=client_secret,
 115            client_id=client_id,
 116            settings=settings,
 117            max_retries=max_retries,
 118            debug=debug,
 119        )
 120
 121        self._framework = framework.Framework()
 122
 123    @property
 124    def framework(self) -> api.Framework:
 125        return self._framework
 126
 127    @property
 128    def rest(self) -> api.RESTClient:
 129        return self._rest
 130
 131    @property
 132    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
 133        return self._rest.metadata
 134
 135    @property
 136    def settings(self) -> builders.Settings:
 137        return self._rest.settings
 138
 139    # * User methods.
 140
 141    async def fetch_current_user_memberships(self, access_token: str, /) -> user.User:
 142        """Fetch and return a user object of the bungie net user associated with account.
 143
 144        .. warning::
 145            This method requires OAuth2 scope and a Bearer access token.
 146
 147        Parameters
 148        ----------
 149        access_token : `str`
 150            A valid Bearer access token for the authorization.
 151
 152        Returns
 153        -------
 154        `aiobungie.crates.user.User`
 155            A user object includes the Destiny memberships and Bungie.net user.
 156        """
 157        resp = await self._rest.fetch_current_user_memberships(access_token)
 158
 159        return self._framework.deserialize_user(resp)
 160
 161    async def fetch_bungie_user(self, id: int, /) -> user.BungieUser:
 162        """Fetch a Bungie user by their BungieNet id.
 163
 164        Parameters
 165        ----------
 166        id: `int`
 167            The user id.
 168
 169        Returns
 170        -------
 171        `aiobungie.crates.user.BungieUser`
 172            A Bungie user.
 173
 174        Raises
 175        ------
 176        `aiobungie.error.NotFound`
 177            The user was not found.
 178        """
 179        payload = await self._rest.fetch_bungie_user(id)
 180        return self._framework.deserialize_bungie_user(payload)
 181
 182    async def search_users(
 183        self, name: str, /
 184    ) -> sain.Iterator[user.SearchableDestinyUser]:
 185        """Search for players and return all players that matches the same name.
 186
 187        Parameters
 188        ----------
 189        name : `str`
 190            The user name.
 191
 192        Returns
 193        -------
 194        `aiobungie.Iterator[aiobungie.crates.SearchableDestinyUser]`
 195            A sequence of the found users with this name.
 196        """
 197        payload = await self._rest.search_users(name)
 198        return sain.Iter(
 199            self._framework.deserialize_searched_user(user)
 200            for user in payload["searchResults"]
 201        )
 202
 203    async def fetch_user_themes(self) -> collections.Sequence[user.UserThemes]:
 204        """Fetch all available user themes.
 205
 206        Returns
 207        -------
 208        `collections.Sequence[aiobungie.crates.user.UserThemes]`
 209            A sequence of user themes.
 210        """
 211        data = await self._rest.fetch_user_themes()
 212
 213        return self._framework.deserialize_user_themes(data)
 214
 215    async def fetch_hard_types(
 216        self,
 217        credential: int,
 218        type: enums.CredentialType | int = enums.CredentialType.STEAMID,
 219        /,
 220    ) -> user.HardLinkedMembership:
 221        """Gets any hard linked membership given a credential.
 222
 223        Only works for credentials that are public just `aiobungie.CredentialType.STEAMID` right now.
 224        Cross Save aware.
 225
 226        Parameters
 227        ----------
 228        credential: `int`
 229            A valid SteamID64
 230        type: `aiobungie.CredentialType`
 231            The credential type. This must not be changed
 232            Since its only credential that works "currently"
 233
 234        Returns
 235        -------
 236        `aiobungie.crates.user.HardLinkedMembership`
 237            Information about the hard linked data.
 238        """
 239
 240        payload = await self._rest.fetch_hardlinked_credentials(credential, type)
 241
 242        return user.HardLinkedMembership(
 243            id=int(payload["membershipId"]),
 244            type=enums.MembershipType(payload["membershipType"]),
 245            cross_save_type=enums.MembershipType(payload["CrossSaveOverriddenType"]),
 246        )
 247
 248    async def fetch_membership_from_id(
 249        self,
 250        id: int,
 251        /,
 252        type: enums.MembershipType | int = enums.MembershipType.NONE,
 253    ) -> user.User:
 254        """Fetch a Bungie user's memberships from their Bungie ID.
 255
 256        This method returns both Bungie user and its Destiny 2 memberships bound to it.
 257
 258        Parameters
 259        ----------
 260        id : `int`
 261            A Bungie.net user's ID. It looks something like this `20315338`
 262        type : `aiobungie.MembershipType`
 263            The user's membership type. This is optional.
 264
 265        Returns
 266        -------
 267        `aiobungie.crates.User`
 268            A Bungie user with their membership types.
 269
 270        Raises
 271        ------
 272        `aiobungie.NotFound`
 273            The requested user was not found.
 274        """
 275        payload = await self._rest.fetch_membership_from_id(id, type)
 276
 277        return self._framework.deserialize_user(payload)
 278
 279    async def fetch_user_credentials(
 280        self, access_token: str, membership_id: int, /
 281    ) -> collections.Sequence[user.UserCredentials]:
 282        """Fetch an array of credential types attached to the requested account.
 283
 284        .. note::
 285            This method require OAuth2 Bearer access token.
 286
 287        Parameters
 288        ----------
 289        access_token : `str`
 290            The bearer access token associated with the bungie account.
 291        membership_id : `int`
 292            The id of the membership to return.
 293
 294        Returns
 295        -------
 296        `collections.Sequence[aiobungie.crates.UserCredentials]`
 297            A sequence of the attached user credentials.
 298
 299        Raises
 300        ------
 301        `aiobungie.Unauthorized`
 302            The access token was wrong or no access token passed.
 303        """
 304        resp = await self._rest.fetch_user_credentials(access_token, membership_id)
 305
 306        return self._framework.deserialize_user_credentials(resp)
 307
 308    async def fetch_sanitized_membership(
 309        self, membership_id: int, /
 310    ) -> user.SanitizedMembership:
 311        """Fetch a list of all display names linked to `membership_id`, Which is profanity filtered.
 312
 313        Parameters
 314        ----------
 315        membership_id: `int`
 316            The membership ID to fetch
 317
 318        Returns
 319        -------
 320        `aiobungie.crates.SanitizedMembership`
 321            A JSON object contains all the available display names.
 322        """
 323        response = await self._rest.fetch_sanitized_membership(membership_id)
 324        return self._framework.deserialize_sanitized_membership(response)
 325
 326    # * Destiny 2.
 327
 328    async def fetch_profile(
 329        self,
 330        member_id: int,
 331        type: enums.MembershipType | int,
 332        components: collections.Sequence[enums.ComponentType],
 333        auth: str | None = None,
 334    ) -> components.Component:
 335        """Fetch a Bungie profile with the required components.
 336
 337        Example
 338        -------
 339        ```py
 340        my_profile_id = 4611686018484639825
 341        my_profile = await client.fetch_profile(
 342            my_profile_id,
 343            MembershipType.STEAM,
 344            components=(ComponentType.CHARACTERS,)
 345        )
 346        characters = my_profile.characters
 347        if characters is not None:
 348            for character in characters.values():
 349                print(character.power_level)
 350        ```
 351
 352        Parameters
 353        ----------
 354        member_id: `int`
 355            The profile membership's id.
 356        type: `aiobungie.MembershipType`
 357            The profile's membership type.
 358        components : `collections.Sequence[aiobungie.ComponentType]`
 359            A sequence of components to collect. If the sequence is empty, then all components will be `None`.
 360
 361        Other Parameters
 362        ----------------
 363        auth : `str | None`
 364            A Bearer access_token to make the request with.
 365            This is optional and limited to components that only requires an Authorization token.
 366
 367        Returns
 368        --------
 369        `aiobungie.crates.Component`
 370            A Destiny 2 player profile with its components.
 371            Only passed components will be available if they exists. Otherwise they will be `None`
 372
 373        Raises
 374        ------
 375        `aiobungie.MembershipTypeError`
 376            The provided membership type was invalid.
 377        """
 378        data = await self._rest.fetch_profile(member_id, type, components, auth)
 379        return self._framework.deserialize_components(data)
 380
 381    async def fetch_linked_profiles(
 382        self,
 383        member_id: int,
 384        member_type: enums.MembershipType | int,
 385        /,
 386        *,
 387        all: bool = False,
 388    ) -> profile.LinkedProfile:
 389        """Returns a summary information about all profiles linked to the requested member.
 390
 391        The passed membership id/type maybe a Bungie.Net membership or a Destiny memberships.
 392
 393        .. note::
 394            It will only return linked accounts whose linkages you are allowed to view.
 395
 396        Parameters
 397        ----------
 398        member_id : `int`
 399            The ID of the membership. This must be a valid Bungie.Net or PSN or Xbox ID.
 400        member_type : `aiobungie.MembershipType`
 401            The type for the membership whose linked Destiny account you want to return.
 402
 403        Other Parameters
 404        ----------------
 405        all : `bool`
 406            If provided and set to `True`, All memberships regardless
 407            of whether they're obscured by overrides will be returned,
 408
 409            If provided and set to `False`, Only available memberships will be returned.
 410            The default for this is `False`.
 411
 412        Returns
 413        -------
 414        `aiobungie.crates.profile.LinkedProfile`
 415            A linked profile object.
 416        """
 417        resp = await self._rest.fetch_linked_profiles(member_id, member_type, all=all)
 418
 419        return self._framework.deserialize_linked_profiles(resp)
 420
 421    async def fetch_membership(
 422        self,
 423        name: str,
 424        code: int,
 425        /,
 426        type: enums.MembershipType | int = enums.MembershipType.ALL,
 427    ) -> collections.Sequence[user.DestinyMembership]:
 428        """Fetch a Destiny 2 player's memberships.
 429
 430        Parameters
 431        -----------
 432        name: `str`
 433            The unique Bungie player name.
 434        code : `int`
 435            The unique Bungie display name code.
 436        type: `aiobungie.internal.enums.MembershipType`
 437            The player's membership type, e,g. XBOX, STEAM, PSN
 438
 439        Returns
 440        --------
 441        `collections.Sequence[aiobungie.crates.DestinyMembership]`
 442            A sequence of the found Destiny 2 player memberships.
 443            An empty sequence will be returned if no one found.
 444
 445        Raises
 446        ------
 447        `aiobungie.MembershipTypeError`
 448            The provided membership type was invalid.
 449        """
 450        resp = await self._rest.fetch_membership(name, code, type)
 451
 452        return self._framework.deserialize_destiny_memberships(resp)
 453
 454    async def fetch_character(
 455        self,
 456        member_id: int,
 457        membership_type: enums.MembershipType | int,
 458        character_id: int,
 459        components: collections.Sequence[enums.ComponentType],
 460        auth: str | None = None,
 461    ) -> components.CharacterComponent:
 462        """Fetch a Destiny 2 character.
 463
 464        Example
 465        -------
 466        ```py
 467        membership_id, titan_id = 0, 0
 468        my_character = await client.fetch_character(
 469            membership_id,
 470            MembershipType.STEAM,
 471            titan_id,
 472            components=(ComponentType.CHARACTER_INVENTORIES,)
 473        )
 474        inventory = my_character.inventory
 475        if inventory is not None:
 476            for item in inventory.values():
 477                print(item)
 478        ```
 479
 480        Parameters
 481        ----------
 482        member_id: `int`
 483            A valid bungie member id.
 484        character_id: `int`
 485            The Destiny character id to retrieve.
 486        membership_type: `aiobungie.internal.enums.MembershipType`
 487            The member's membership type.
 488        components: `collections.Sequence[aiobungie.ComponentType]`
 489            Multiple arguments of character components to collect and return.
 490
 491        Other Parameters
 492        ----------------
 493        auth : `str | None`
 494            A Bearer access_token to make the request with.
 495            This is optional and limited to components that only requires an Authorization token.
 496
 497        Returns
 498        -------
 499        `aiobungie.crates.CharacterComponent`
 500            A Bungie character component.
 501
 502        `aiobungie.MembershipTypeError`
 503            The provided membership type was invalid.
 504        """
 505        resp = await self._rest.fetch_character(
 506            member_id, membership_type, character_id, components, auth
 507        )
 508
 509        return self._framework.deserialize_character_component(resp)
 510
 511    async def fetch_unique_weapon_history(
 512        self,
 513        membership_id: int,
 514        character_id: int,
 515        membership_type: enums.MembershipType | int,
 516    ) -> collections.Sequence[activity.ExtendedWeaponValues]:
 517        """Fetch details about unique weapon usage for a character. Includes all exotics.
 518
 519        Parameters
 520        ----------
 521        membership_id : `int`
 522            The Destiny user membership id.
 523        character_id : `int`
 524            The character id to retrieve.
 525        membership_type : `aiobungie.aiobungie.MembershipType | int`
 526            The Destiny user's membership type.
 527
 528        Returns
 529        -------
 530        `collections.Sequence[aiobungie.crates.ExtendedWeaponValues]`
 531            A sequence of the weapon's extended values.
 532        """
 533        resp = await self._rest.fetch_unique_weapon_history(
 534            membership_id, character_id, membership_type
 535        )
 536
 537        return tuple(
 538            self._framework.deserialize_extended_weapon_values(weapon)
 539            for weapon in resp["weapons"]
 540        )
 541
 542    # * Destiny 2 Activities.
 543
 544    async def fetch_activities(
 545        self,
 546        member_id: int,
 547        character_id: int,
 548        mode: enums.GameMode | int,
 549        membership_type: enums.MembershipType | int,
 550        *,
 551        page: int = 0,
 552        limit: int = 250,
 553    ) -> sain.Iterator[activity.Activity]:
 554        """Fetch a Destiny 2 activity for the specified character id.
 555
 556        Parameters
 557        ----------
 558        member_id: `int`
 559            The user id that starts with `4611`.
 560        character_id: `int`
 561            The id of the character to retrieve the activities for.
 562        mode: `aiobungie.aiobungie.internal.enums.GameMode | int`
 563            This parameter filters the game mode, Nightfall, Strike, Iron Banner, etc.
 564        membership_type: `aiobungie.internal.enums.MembershipType`
 565            The Destiny 2 membership type.
 566
 567        Other Parameters
 568        ----------------
 569        page: int
 570            The page number. Default is `0`
 571        limit: int
 572            Limit the returned result. Default is `250`.
 573
 574        Returns
 575        -------
 576        `Iterator[aiobungie.crates.Activity]`
 577            An iterator of the player's activities.
 578
 579        Raises
 580        ------
 581        `aiobungie.MembershipTypeError`
 582            The provided membership type was invalid.
 583        """
 584        resp = await self._rest.fetch_activities(
 585            member_id,
 586            character_id,
 587            mode,
 588            membership_type=membership_type,
 589            page=page,
 590            limit=limit,
 591        )
 592
 593        return self._framework.deserialize_activities(resp)
 594
 595    async def fetch_post_activity(self, instance_id: int, /) -> activity.PostActivity:
 596        """Fetch a post activity details.
 597
 598        Parameters
 599        ----------
 600        instance_id: `int`
 601            The activity instance id.
 602
 603        Returns
 604        -------
 605        `aiobungie.crates.PostActivity`
 606           A post activity object.
 607        """
 608        resp = await self._rest.fetch_post_activity(instance_id)
 609
 610        return self._framework.deserialize_post_activity(resp)
 611
 612    async def fetch_aggregated_activity_stats(
 613        self,
 614        character_id: int,
 615        membership_id: int,
 616        membership_type: enums.MembershipType | int,
 617    ) -> sain.Iterator[activity.AggregatedActivity]:
 618        """Fetch aggregated activity stats for a character.
 619
 620        Parameters
 621        ----------
 622        character_id: `int`
 623            The id of the character to retrieve the activities for.
 624        membership_id: `int`
 625            The id of the user that started with `4611`.
 626        membership_type: `aiobungie.internal.enums.MembershipType`
 627            The Member ship type.
 628
 629        Returns
 630        -------
 631        `Iterator[aiobungie.crates.AggregatedActivity]`
 632            An iterator of the player's activities.
 633
 634        Raises
 635        ------
 636        `aiobungie.MembershipTypeError`
 637            The provided membership type was invalid.
 638        """
 639        resp = await self._rest.fetch_aggregated_activity_stats(
 640            character_id, membership_id, membership_type
 641        )
 642
 643        return self._framework.deserialize_aggregated_activities(resp)
 644
 645    # * Destiny 2 Clans or GroupsV2.
 646
 647    async def fetch_clan_from_id(
 648        self,
 649        id: int,
 650        /,
 651        access_token: str | None = None,
 652    ) -> clans.Clan:
 653        """Fetch a Bungie Clan by its id.
 654
 655        Parameters
 656        -----------
 657        id: `int`
 658            The clan id.
 659
 660        Returns
 661        --------
 662        `aiobungie.crates.Clan`
 663            An Bungie clan.
 664
 665        Raises
 666        ------
 667        `aiobungie.NotFound`
 668            The clan was not found.
 669        """
 670        resp = await self._rest.fetch_clan_from_id(id, access_token)
 671
 672        return self._framework.deserialize_clan(resp)
 673
 674    async def fetch_clan(
 675        self,
 676        name: str,
 677        /,
 678        access_token: str | None = None,
 679        *,
 680        type: enums.GroupType | int = enums.GroupType.CLAN,
 681    ) -> clans.Clan:
 682        """Fetch a Clan by its name.
 683        This method will return the first clan found with given name.
 684
 685        Parameters
 686        ----------
 687        name: `str`
 688            The clan name
 689
 690        Other Parameters
 691        ----------------
 692        access_token : `str | None`
 693            An optional access token to make the request with.
 694
 695            If the token was bound to a member of the clan,
 696            This field `aiobungie.crates.Clan.current_user_membership` will be available
 697            and will return the membership of the user who made this request.
 698        type : `aiobungie.GroupType`
 699            The group type, Default is aiobungie.GroupType.CLAN.
 700
 701        Returns
 702        -------
 703        `aiobungie.crates.Clan`
 704            A Bungie clan.
 705
 706        Raises
 707        ------
 708        `aiobungie.NotFound`
 709            The clan was not found.
 710        """
 711        resp = await self._rest.fetch_clan(name, access_token, type=type)
 712
 713        return self._framework.deserialize_clan(resp)
 714
 715    async def fetch_clan_conversations(
 716        self, clan_id: int, /
 717    ) -> collections.Sequence[clans.ClanConversation]:
 718        """Fetch the conversations/chat channels of the given clan id.
 719
 720        Parameters
 721        ----------
 722        clan_id : `int`
 723            The clan id.
 724
 725        Returns
 726        `collections.Sequence[aiobungie.crates.ClanConversation]`
 727            A sequence of the clan chat channels.
 728        """
 729        resp = await self._rest.fetch_clan_conversations(clan_id)
 730
 731        return self._framework.deserialize_clan_conversations(resp)
 732
 733    async def fetch_clan_admins(
 734        self, clan_id: int, /
 735    ) -> sain.Iterator[clans.ClanMember]:
 736        """Fetch the clan founder and admins.
 737
 738        Parameters
 739        ----------
 740        clan_id : `int`
 741            The clan id.
 742
 743        Returns
 744        -------
 745        `aiobungie.Iterator[aiobungie.crates.ClanMember]`
 746            An iterator over the found clan admins and founder.
 747
 748        Raises
 749        ------
 750        `aiobungie.NotFound`
 751            The requested clan was not found.
 752        """
 753        resp = await self._rest.fetch_clan_admins(clan_id)
 754
 755        return self._framework.deserialize_clan_members(resp)
 756
 757    async def fetch_groups_for_member(
 758        self,
 759        member_id: int,
 760        member_type: enums.MembershipType | int,
 761        /,
 762        *,
 763        filter: int = 0,
 764        group_type: enums.GroupType = enums.GroupType.CLAN,
 765    ) -> collections.Sequence[clans.GroupMember]:
 766        """Fetch information about the groups that a given member has joined.
 767
 768        Parameters
 769        ----------
 770        member_id : `int`
 771            The member's id
 772        member_type : `aiobungie.MembershipType`
 773            The member's membership type.
 774
 775        Other Parameters
 776        ----------------
 777        filter : `int`
 778            Filter apply to list of joined groups. This Default to `0`
 779        group_type : `aiobungie.GroupType`
 780            The group's type.
 781            This is always set to `aiobungie.GroupType.CLAN` and should not be changed.
 782
 783        Returns
 784        -------
 785        `collections.Sequence[aiobungie.crates.GroupMember]`
 786            A sequence of joined groups for the fetched member.
 787        """
 788        resp = await self._rest.fetch_groups_for_member(
 789            member_id, member_type, filter=filter, group_type=group_type
 790        )
 791
 792        return tuple(
 793            self._framework.deserialize_group_member(group) for group in resp["results"]
 794        )
 795
 796    async def fetch_potential_groups_for_member(
 797        self,
 798        member_id: int,
 799        member_type: enums.MembershipType | int,
 800        /,
 801        *,
 802        filter: int = 0,
 803        group_type: enums.GroupType | int = enums.GroupType.CLAN,
 804    ) -> collections.Sequence[clans.GroupMember]:
 805        """Fetch the potential groups for a clan member.
 806
 807        Parameters
 808        ----------
 809        member_id : `int`
 810            The member's id
 811        member_type : `aiobungie.aiobungie.MembershipType | int`
 812            The member's membership type.
 813
 814        Other Parameters
 815        ----------------
 816        filter : `int`
 817            Filter apply to list of joined groups. This Default to `0`
 818        group_type : `aiobungie.aiobungie.GroupType | int`
 819            The group's type.
 820            This is always set to `aiobungie.GroupType.CLAN` and should not be changed.
 821
 822        Returns
 823        -------
 824        `collections.Sequence[aiobungie.crates.GroupMember]`
 825            A sequence of joined potential groups for the fetched member.
 826        """
 827        resp = await self._rest.fetch_potential_groups_for_member(
 828            member_id, member_type, filter=filter, group_type=group_type
 829        )
 830
 831        return tuple(
 832            self._framework.deserialize_group_member(group) for group in resp["results"]
 833        )
 834
 835    async def fetch_clan_members(
 836        self,
 837        clan_id: int,
 838        /,
 839        *,
 840        name: str | None = None,
 841        type: enums.MembershipType | int = enums.MembershipType.NONE,
 842    ) -> sain.Iterator[clans.ClanMember]:
 843        """Fetch Bungie clan members.
 844
 845        Parameters
 846        ----------
 847        clan_id : `int`
 848            The clans id
 849
 850        Other Parameters
 851        ----------------
 852        name : `str | None`
 853            If provided, Only players matching this name will be returned.
 854        type : `aiobungie.MembershipType`
 855            An optional clan member's membership type.
 856            This parameter is used to filter the returned results
 857            by the provided membership, For an example XBox memberships only,
 858            Otherwise will return all memberships.
 859
 860        Returns
 861        -------
 862        `Iterator[aiobungie.crates.ClanMember]`
 863            An iterator over the bungie clan members.
 864
 865        Raises
 866        ------
 867        `aiobungie.NotFound`
 868            The clan was not found.
 869        """
 870        resp = await self._rest.fetch_clan_members(clan_id, type=type, name=name)
 871
 872        return self._framework.deserialize_clan_members(resp)
 873
 874    async def fetch_clan_banners(self) -> collections.Sequence[clans.ClanBanner]:
 875        """Fetch the clan banners.
 876
 877        Returns
 878        -------
 879        `collections.Sequence[aiobungie.crates.ClanBanner]`
 880            A sequence of the clan banners.
 881        """
 882        resp = await self._rest.fetch_clan_banners()
 883
 884        return self._framework.deserialize_clan_banners(resp)
 885
 886    # This method is required to be here since it deserialize the clan.
 887    async def kick_clan_member(
 888        self,
 889        access_token: str,
 890        /,
 891        group_id: int,
 892        membership_id: int,
 893        membership_type: enums.MembershipType | int,
 894    ) -> clans.Clan:
 895        """Kick a member from the clan.
 896
 897        .. note::
 898            This request requires OAuth2: oauth2: `AdminGroups` scope.
 899
 900        Parameters
 901        ----------
 902        access_token : `str`
 903            The bearer access token associated with the bungie account.
 904        group_id: `int`
 905            The group id.
 906        membership_id : `int`
 907            The member id to kick.
 908        membership_type : `aiobungie.aiobungie.MembershipType | int`
 909            The member's membership type.
 910
 911        Returns
 912        -------
 913        `aiobungie.crates.clan.Clan`
 914            The clan that the member was kicked from.
 915        """
 916        resp = await self._rest.kick_clan_member(
 917            access_token,
 918            group_id=group_id,
 919            membership_id=membership_id,
 920            membership_type=membership_type,
 921        )
 922
 923        return self._framework.deserialize_clan(resp)
 924
 925    async def fetch_clan_weekly_rewards(self, clan_id: int) -> milestones.Milestone:
 926        """Fetch a Bungie clan's weekly reward state.
 927
 928        Parameters
 929        ----------
 930        clan_id : `int`
 931            The clan's id.
 932
 933        Returns
 934        -------
 935        `aiobungie.crates.Milestone`
 936            A runtime status of the clan's milestone data.
 937        """
 938
 939        resp = await self._rest.fetch_clan_weekly_rewards(clan_id)
 940
 941        return self._framework.deserialize_milestone(resp)
 942
 943    async def search_group(
 944        self,
 945        name: str,
 946        group_type: enums.GroupType | int,
 947        *,
 948        creation_date: clans.GroupDate | int = 0,
 949        sort_by: int | None = None,
 950        group_member_count_filter: typing.Literal[0, 1, 2, 3] | None = None,
 951        locale_filter: str | None = None,
 952        tag_text: str | None = None,
 953        items_per_page: int | None = None,
 954        current_page: int | None = None,
 955        request_token: str | None = None,
 956    ) -> collections.Sequence[clans.Group]:
 957        """Search for groups.
 958
 959        .. note::
 960            If the group type is set to `CLAN`, then parameters `group_member_count_filter`,
 961            `locale_filter` and `tag_text` must be `None`, otherwise `ValueError` will be raised.
 962
 963        Parameters
 964        ----------
 965        name : `str`
 966            The group name.
 967        group_type : `aiobungie.GroupType | int`
 968            The group type that's being searched for.
 969
 970        Other Parameters
 971        ----------------
 972        creation_date : `aiobungie.GroupDate | int`
 973            The creation date of the group. Defaults to `0` which is all time.
 974        sort_by : `int | None`
 975            ...
 976        group_member_count_filter : `int | None`
 977            ...
 978        locale_filter : `str | None`
 979            ...
 980        tag_text : `str | None`
 981            ...
 982        items_per_page : `int | None`
 983            ...
 984        current_page : `int | None`
 985            ...
 986        request_token : `str | None`
 987            ...
 988
 989        Returns
 990        --------
 991        `collections.Sequence[aiobungie.crates.Group]`
 992            An array that contains the groups that match the search criteria.
 993
 994        Raises
 995        ------
 996        `ValueError`
 997            If the group type is `aiobungie.GroupType.CLAN` and `group_member_count_filter`,
 998            `locale_filter` and `tag_text` are not `None`.
 999        """
1000        response = await self._rest.search_group(
1001            name,
1002            group_type,
1003            sort_by=sort_by,
1004            creation_date=creation_date,
1005            group_member_count_filter=group_member_count_filter,
1006            locale_filter=locale_filter,
1007            tag_text=tag_text,
1008            items_per_page=items_per_page,
1009            current_page=current_page,
1010            request_token=request_token,
1011        )
1012        return tuple(
1013            self._framework.deserialize_group(result) for result in response["results"]
1014        )
1015
1016    # * Destiny 2 Entities aka Definitions.
1017
1018    async def fetch_inventory_item(self, hash: int, /) -> entity.InventoryEntity:
1019        """Fetch a static inventory item entity given a its hash.
1020
1021        Parameters
1022        ----------
1023        hash: `int`
1024            Inventory item's hash.
1025
1026        Returns
1027        -------
1028        `aiobungie.crates.InventoryEntity`
1029            A bungie inventory item.
1030        """
1031        resp = await self._rest.fetch_inventory_item(hash)
1032
1033        return self._framework.deserialize_inventory_entity(resp)
1034
1035    async def fetch_objective_entity(self, hash: int, /) -> entity.ObjectiveEntity:
1036        """Fetch a Destiny objective entity given a its hash.
1037
1038        Parameters
1039        ----------
1040        hash: `int`
1041            objective's hash.
1042
1043        Returns
1044        -------
1045        `aiobungie.crates.ObjectiveEntity`
1046            An objective entity item.
1047        """
1048        resp = await self._rest.fetch_objective_entity(hash)
1049
1050        return self._framework.deserialize_objective_entity(resp)
1051
1052    @helpers.unstable
1053    async def search_entities(
1054        self, name: str, entity_type: str, *, page: int = 0
1055    ) -> sain.Iterator[entity.SearchableEntity]:
1056        """Search for Destiny2 entities given a name and its type.
1057
1058        Parameters
1059        ----------
1060        name : `str`
1061            The name of the entity, i.e., Thunderlord, One thousand voices.
1062        entity_type : `str`
1063            The type of the entity, AKA Definition,
1064            For an example `DestinyInventoryItemDefinition` for emblems, weapons, and other inventory items.
1065
1066        Other Parameters
1067        ----------------
1068        page : `int`
1069            An optional page to return. Default to 0.
1070
1071        Returns
1072        -------
1073        `Iterator[aiobungie.crates.SearchableEntity]`
1074            An iterator over the found results matching the provided name.
1075        """
1076        # resp = await self._rest.search_entities(name, entity_type, page=page)
1077        # calling this method will raise anyways.
1078        raise
1079
1080    # Fireteams
1081
1082    @helpers.unstable
1083    async def fetch_fireteams(
1084        self,
1085        activity_type: fireteams.FireteamActivity | int,
1086        *,
1087        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1088        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1089        date_range: int = 0,
1090        page: int = 0,
1091        slots_filter: int = 0,
1092    ) -> collections.Sequence[fireteams.Fireteam]:
1093        """Fetch public Bungie fireteams with open slots.
1094
1095        Parameters
1096        ----------
1097        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1098            The fireteam activity type.
1099
1100        Other Parameters
1101        ----------------
1102        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1103            If this is provided. Then the results will be filtered with the given platform.
1104            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1105        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1106            A locale language to filter the used language in that fireteam.
1107            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1108        date_range : `int`
1109            An integer to filter the date range of the returned fireteams. Defaults to `aiobungie.FireteamDate.ALL`.
1110        page : `int`
1111            The page number. By default its `0` which returns all available activities.
1112        slots_filter : `int`
1113            Filter the returned fireteams based on available slots. Default is `0`
1114
1115        Returns
1116        -------
1117        `collections.Sequence[fireteams.Fireteam]`
1118            A sequence of `aiobungie.crates.Fireteam`.
1119        """
1120
1121        # resp = await self._rest.fetch_fireteams(
1122        #     activity_type,
1123        #     platform=platform,
1124        #     language=language,
1125        #     date_range=date_range,
1126        #     page=page,
1127        #     slots_filter=slots_filter,
1128        # )
1129
1130        # return self._framework.deserialize_fireteams(resp)
1131        # ! unreachable
1132        raise
1133
1134    async def fetch_available_clan_fireteams(
1135        self,
1136        access_token: str,
1137        group_id: int,
1138        activity_type: fireteams.FireteamActivity | int,
1139        *,
1140        platform: fireteams.FireteamPlatform | int,
1141        language: fireteams.FireteamLanguage | str,
1142        date_range: int = 0,
1143        page: int = 0,
1144        public_only: bool = False,
1145        slots_filter: int = 0,
1146    ) -> collections.Sequence[fireteams.Fireteam]:
1147        """Fetch a clan's fireteams with open slots.
1148
1149        .. note::
1150            This method requires OAuth2: ReadGroups scope.
1151
1152        Parameters
1153        ----------
1154        access_token : `str`
1155            The bearer access token associated with the bungie account.
1156        group_id : `int`
1157            The group/clan id of the fireteam.
1158        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1159            The fireteam activity type.
1160
1161        Other Parameters
1162        ----------------
1163        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1164            If this is provided. Then the results will be filtered with the given platform.
1165            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1166        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1167            A locale language to filter the used language in that fireteam.
1168            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1169        date_range : `int`
1170            An integer to filter the date range of the returned fireteams. Defaults to `0`.
1171        page : `int`
1172            The page number. By default its `0` which returns all available activities.
1173        public_only: `bool`
1174            If set to True, Then only public fireteams will be returned.
1175        slots_filter : `int`
1176            Filter the returned fireteams based on available slots. Default is `0`
1177
1178        Returns
1179        -------
1180        `collections.Sequence[aiobungie.crates.Fireteam]`
1181            A sequence of  fireteams found in the clan.
1182            `None` will be returned if nothing was found.
1183        """
1184        resp = await self._rest.fetch_available_clan_fireteams(
1185            access_token,
1186            group_id,
1187            activity_type,
1188            platform=platform,
1189            language=language,
1190            date_range=date_range,
1191            page=page,
1192            public_only=public_only,
1193            slots_filter=slots_filter,
1194        )
1195
1196        return self._framework.deserialize_fireteams(resp)
1197
1198    async def fetch_clan_fireteam(
1199        self, access_token: str, fireteam_id: int, group_id: int
1200    ) -> fireteams.AvailableFireteam:
1201        """Fetch a specific clan fireteam.
1202
1203        .. note::
1204            This method requires OAuth2: ReadGroups scope.
1205
1206        Parameters
1207        ----------
1208        access_token : `str`
1209            The bearer access token associated with the bungie account.
1210        group_id : `int`
1211            The group/clan id to fetch the fireteam from.
1212        fireteam_id : `int`
1213            The fireteam id to fetch.
1214
1215        Returns
1216        -------
1217        `aiobungie.crates.AvailableFireteam`
1218            A sequence of available fireteams objects.
1219        """
1220        resp = await self._rest.fetch_clan_fireteam(access_token, fireteam_id, group_id)
1221
1222        return self._framework.deserialize_available_fireteam(resp)
1223
1224    async def fetch_my_clan_fireteams(
1225        self,
1226        access_token: str,
1227        group_id: int,
1228        *,
1229        include_closed: bool = True,
1230        platform: fireteams.FireteamPlatform | int,
1231        language: fireteams.FireteamLanguage | str,
1232        filtered: bool = True,
1233        page: int = 0,
1234    ) -> collections.Sequence[fireteams.AvailableFireteam]:
1235        """A method that's similar to `fetch_fireteams` but requires OAuth2.
1236
1237        .. note::
1238            This method requires OAuth2: ReadGroups scope.
1239
1240        Parameters
1241        ----------
1242        access_token : str
1243            The bearer access token associated with the bungie account.
1244        group_id : int
1245            The group/clan id to fetch.
1246
1247        Other Parameters
1248        ----------------
1249        include_closed : `bool`
1250            If provided and set to True, It will also return closed fireteams.
1251            If provided and set to False, It will only return public fireteams. Default is True.
1252        platform : aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int
1253            If this is provided. Then the results will be filtered with the given platform.
1254            Defaults to aiobungie.crates.FireteamPlatform.ANY which returns all platforms.
1255        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1256            A locale language to filter the used language in that fireteam.
1257            Defaults to aiobungie.crates.FireteamLanguage.ALL
1258        filtered : `bool`
1259            If set to True, it will filter by clan. Otherwise not. Default is True.
1260        page : `int`
1261            The page number. By default its 0 which returns all available activities.
1262
1263        Returns
1264        -------
1265        `collections.Sequence[aiobungie.crates.AvailableFireteam]`
1266            A sequence of available fireteams objects if exists. else `None` will be returned.
1267        """
1268        resp = await self._rest.fetch_my_clan_fireteams(
1269            access_token,
1270            group_id,
1271            include_closed=include_closed,
1272            platform=platform,
1273            language=language,
1274            filtered=filtered,
1275            page=page,
1276        )
1277
1278        return self._framework.deserialize_available_fireteams(resp)
1279
1280    # Friends and social.
1281
1282    async def fetch_friends(
1283        self, access_token: str, /
1284    ) -> collections.Sequence[friends.Friend]:
1285        """Fetch bungie friend list.
1286
1287        .. note::
1288            This requests OAuth2: ReadUserData scope.
1289
1290        Parameters
1291        -----------
1292        access_token : `str`
1293            The bearer access token associated with the bungie account.
1294
1295        Returns
1296        -------
1297        `collections.Sequence[aiobungie.crates.Friend]`
1298            A sequence of the friends associated with that access token.
1299        """
1300
1301        resp = await self._rest.fetch_friends(access_token)
1302
1303        return self._framework.deserialize_friends(resp)
1304
1305    async def fetch_friend_requests(
1306        self, access_token: str, /
1307    ) -> friends.FriendRequestView:
1308        """Fetch pending bungie friend requests queue.
1309
1310        .. note::
1311            This requests OAuth2: ReadUserData scope.
1312
1313        Parameters
1314        -----------
1315        access_token : `str`
1316            The bearer access token associated with the bungie account.
1317
1318        Returns
1319        -------
1320        `aiobungie.crates.FriendRequestView`
1321            A friend requests view of that associated access token.
1322        """
1323
1324        resp = await self._rest.fetch_friend_requests(access_token)
1325
1326        return self._framework.deserialize_friend_requests(resp)
1327
1328    # Applications and Developer portal.
1329
1330    async def fetch_application(self, appid: int, /) -> application.Application:
1331        """Fetch a Bungie application.
1332
1333        Parameters
1334        -----------
1335        appid: `int`
1336            The application id.
1337
1338        Returns
1339        --------
1340        `aiobungie.crates.Application`
1341            A Bungie application.
1342        """
1343        resp = await self._rest.fetch_application(appid)
1344
1345        return self._framework.deserialize_application(resp)
1346
1347    # Milestones
1348
1349    async def fetch_public_milestone_content(
1350        self, milestone_hash: int, /
1351    ) -> milestones.MilestoneContent:
1352        """Fetch the milestone content given its hash.
1353
1354        Parameters
1355        ----------
1356        milestone_hash : `int`
1357            The milestone hash.
1358
1359        Returns
1360        -------
1361        `aiobungie.crates.milestones.MilestoneContent`
1362            A milestone content object.
1363        """
1364        ...
1365        resp = await self._rest.fetch_public_milestone_content(milestone_hash)
1366        return self._framework.deserialize_public_milestone_content(resp)

Compact standard client implementation.

This client is the way to be able to start sending requests over the REST API and receiving deserialized response objects.

Refer to aiobungie.RESTClient if you prefer to use a more lower-level client.

Example
import aiobungie
import asyncio

async def main():
    client = aiobungie.Client('token')
    async with client.rest:
        user = await client.fetch_bungie_user(20315338)
        print(user)

asyncio.run(main())
Parameters
  • token (str): Your Bungie's API key or Token from the developer's portal.
Other Parameters
  • client_secret (str | None): An optional application client secret, This is only needed if you're fetching OAuth2 tokens with this client.
  • client_id (int | None): An optional application client id, This is only needed if you're fetching OAuth2 tokens with this client.
  • settings (aiobungie.builders.Settings | None): The client settings to use, if None the default will be used.
  • max_retries (int): The max retries number to retry if the request hit a 5xx status code.
  • debug ("TRACE" | bool | int): The level of logging to enable.
Client( token: 'str', /, *, client_secret: 'str | None' = None, client_id: 'int | None' = None, settings: 'builders.Settings | None' = None, max_retries: 'int' = 4, debug: "typing.Literal['TRACE'] | bool | int" = False)
101    def __init__(
102        self,
103        token: str,
104        /,
105        *,
106        client_secret: str | None = None,
107        client_id: int | None = None,
108        settings: builders.Settings | None = None,
109        max_retries: int = 4,
110        debug: typing.Literal["TRACE"] | bool | int = False,
111    ) -> None:
112        self._rest = rest_.RESTClient(
113            token,
114            client_secret=client_secret,
115            client_id=client_id,
116            settings=settings,
117            max_retries=max_retries,
118            debug=debug,
119        )
120
121        self._framework = framework.Framework()
framework: 'api.Framework'
123    @property
124    def framework(self) -> api.Framework:
125        return self._framework

An implementation of a aiobungie.api.Framework object used by your client.

rest: 'api.RESTClient'
127    @property
128    def rest(self) -> api.RESTClient:
129        return self._rest

Returns the REST client for the this client.

metadata: 'collections.MutableMapping[typing.Any, typing.Any]'
131    @property
132    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
133        return self._rest.metadata

A mutable mapping storage for the user's needs.

settings: 'builders.Settings'
135    @property
136    def settings(self) -> builders.Settings:
137        return self._rest.settings

Internal client settings used within the HTTP client session.

async def fetch_current_user_memberships(self, access_token: 'str', /) -> 'user.User':
141    async def fetch_current_user_memberships(self, access_token: str, /) -> user.User:
142        """Fetch and return a user object of the bungie net user associated with account.
143
144        .. warning::
145            This method requires OAuth2 scope and a Bearer access token.
146
147        Parameters
148        ----------
149        access_token : `str`
150            A valid Bearer access token for the authorization.
151
152        Returns
153        -------
154        `aiobungie.crates.user.User`
155            A user object includes the Destiny memberships and Bungie.net user.
156        """
157        resp = await self._rest.fetch_current_user_memberships(access_token)
158
159        return self._framework.deserialize_user(resp)

Fetch and return a user object of the bungie net user associated with account.

This method requires OAuth2 scope and a Bearer access token.

Parameters
  • access_token (str): A valid Bearer access token for the authorization.
Returns
async def fetch_bungie_user(self, id: 'int', /) -> 'user.BungieUser':
161    async def fetch_bungie_user(self, id: int, /) -> user.BungieUser:
162        """Fetch a Bungie user by their BungieNet id.
163
164        Parameters
165        ----------
166        id: `int`
167            The user id.
168
169        Returns
170        -------
171        `aiobungie.crates.user.BungieUser`
172            A Bungie user.
173
174        Raises
175        ------
176        `aiobungie.error.NotFound`
177            The user was not found.
178        """
179        payload = await self._rest.fetch_bungie_user(id)
180        return self._framework.deserialize_bungie_user(payload)

Fetch a Bungie user by their BungieNet id.

Parameters
  • id (int): The user id.
Returns
Raises
async def search_users(self, name: 'str', /) -> 'sain.Iterator[user.SearchableDestinyUser]':
182    async def search_users(
183        self, name: str, /
184    ) -> sain.Iterator[user.SearchableDestinyUser]:
185        """Search for players and return all players that matches the same name.
186
187        Parameters
188        ----------
189        name : `str`
190            The user name.
191
192        Returns
193        -------
194        `aiobungie.Iterator[aiobungie.crates.SearchableDestinyUser]`
195            A sequence of the found users with this name.
196        """
197        payload = await self._rest.search_users(name)
198        return sain.Iter(
199            self._framework.deserialize_searched_user(user)
200            for user in payload["searchResults"]
201        )

Search for players and return all players that matches the same name.

Parameters
  • name (str): The user name.
Returns
async def fetch_user_themes(self) -> 'collections.Sequence[user.UserThemes]':
203    async def fetch_user_themes(self) -> collections.Sequence[user.UserThemes]:
204        """Fetch all available user themes.
205
206        Returns
207        -------
208        `collections.Sequence[aiobungie.crates.user.UserThemes]`
209            A sequence of user themes.
210        """
211        data = await self._rest.fetch_user_themes()
212
213        return self._framework.deserialize_user_themes(data)

Fetch all available user themes.

Returns
async def fetch_hard_types( self, credential: 'int', type: 'enums.CredentialType | int' = <CredentialType.STEAMID: 12>, /) -> 'user.HardLinkedMembership':
215    async def fetch_hard_types(
216        self,
217        credential: int,
218        type: enums.CredentialType | int = enums.CredentialType.STEAMID,
219        /,
220    ) -> user.HardLinkedMembership:
221        """Gets any hard linked membership given a credential.
222
223        Only works for credentials that are public just `aiobungie.CredentialType.STEAMID` right now.
224        Cross Save aware.
225
226        Parameters
227        ----------
228        credential: `int`
229            A valid SteamID64
230        type: `aiobungie.CredentialType`
231            The credential type. This must not be changed
232            Since its only credential that works "currently"
233
234        Returns
235        -------
236        `aiobungie.crates.user.HardLinkedMembership`
237            Information about the hard linked data.
238        """
239
240        payload = await self._rest.fetch_hardlinked_credentials(credential, type)
241
242        return user.HardLinkedMembership(
243            id=int(payload["membershipId"]),
244            type=enums.MembershipType(payload["membershipType"]),
245            cross_save_type=enums.MembershipType(payload["CrossSaveOverriddenType"]),
246        )

Gets any hard linked membership given a credential.

Only works for credentials that are public just aiobungie.CredentialType.STEAMID right now. Cross Save aware.

Parameters
  • credential (int): A valid SteamID64
  • type (aiobungie.CredentialType): The credential type. This must not be changed Since its only credential that works "currently"
Returns
async def fetch_membership_from_id( self, id: 'int', /, type: 'enums.MembershipType | int' = <MembershipType.NONE: 0>) -> 'user.User':
248    async def fetch_membership_from_id(
249        self,
250        id: int,
251        /,
252        type: enums.MembershipType | int = enums.MembershipType.NONE,
253    ) -> user.User:
254        """Fetch a Bungie user's memberships from their Bungie ID.
255
256        This method returns both Bungie user and its Destiny 2 memberships bound to it.
257
258        Parameters
259        ----------
260        id : `int`
261            A Bungie.net user's ID. It looks something like this `20315338`
262        type : `aiobungie.MembershipType`
263            The user's membership type. This is optional.
264
265        Returns
266        -------
267        `aiobungie.crates.User`
268            A Bungie user with their membership types.
269
270        Raises
271        ------
272        `aiobungie.NotFound`
273            The requested user was not found.
274        """
275        payload = await self._rest.fetch_membership_from_id(id, type)
276
277        return self._framework.deserialize_user(payload)

Fetch a Bungie user's memberships from their Bungie ID.

This method returns both Bungie user and its Destiny 2 memberships bound to it.

Parameters
  • id (int): A Bungie.net user's ID. It looks something like this 20315338
  • type (aiobungie.MembershipType): The user's membership type. This is optional.
Returns
Raises
async def fetch_user_credentials( self, access_token: 'str', membership_id: 'int', /) -> 'collections.Sequence[user.UserCredentials]':
279    async def fetch_user_credentials(
280        self, access_token: str, membership_id: int, /
281    ) -> collections.Sequence[user.UserCredentials]:
282        """Fetch an array of credential types attached to the requested account.
283
284        .. note::
285            This method require OAuth2 Bearer access token.
286
287        Parameters
288        ----------
289        access_token : `str`
290            The bearer access token associated with the bungie account.
291        membership_id : `int`
292            The id of the membership to return.
293
294        Returns
295        -------
296        `collections.Sequence[aiobungie.crates.UserCredentials]`
297            A sequence of the attached user credentials.
298
299        Raises
300        ------
301        `aiobungie.Unauthorized`
302            The access token was wrong or no access token passed.
303        """
304        resp = await self._rest.fetch_user_credentials(access_token, membership_id)
305
306        return self._framework.deserialize_user_credentials(resp)

Fetch an array of credential types attached to the requested account.

This method require OAuth2 Bearer access token.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • membership_id (int): The id of the membership to return.
Returns
Raises
async def fetch_sanitized_membership(self, membership_id: 'int', /) -> 'user.SanitizedMembership':
308    async def fetch_sanitized_membership(
309        self, membership_id: int, /
310    ) -> user.SanitizedMembership:
311        """Fetch a list of all display names linked to `membership_id`, Which is profanity filtered.
312
313        Parameters
314        ----------
315        membership_id: `int`
316            The membership ID to fetch
317
318        Returns
319        -------
320        `aiobungie.crates.SanitizedMembership`
321            A JSON object contains all the available display names.
322        """
323        response = await self._rest.fetch_sanitized_membership(membership_id)
324        return self._framework.deserialize_sanitized_membership(response)

Fetch a list of all display names linked to membership_id, Which is profanity filtered.

Parameters
  • membership_id (int): The membership ID to fetch
Returns
  • aiobungie.crates.SanitizedMembership: A JSON object contains all the available display names.
async def fetch_profile( self, member_id: 'int', type: 'enums.MembershipType | int', components: 'collections.Sequence[enums.ComponentType]', auth: 'str | None' = None) -> 'components.Component':
328    async def fetch_profile(
329        self,
330        member_id: int,
331        type: enums.MembershipType | int,
332        components: collections.Sequence[enums.ComponentType],
333        auth: str | None = None,
334    ) -> components.Component:
335        """Fetch a Bungie profile with the required components.
336
337        Example
338        -------
339        ```py
340        my_profile_id = 4611686018484639825
341        my_profile = await client.fetch_profile(
342            my_profile_id,
343            MembershipType.STEAM,
344            components=(ComponentType.CHARACTERS,)
345        )
346        characters = my_profile.characters
347        if characters is not None:
348            for character in characters.values():
349                print(character.power_level)
350        ```
351
352        Parameters
353        ----------
354        member_id: `int`
355            The profile membership's id.
356        type: `aiobungie.MembershipType`
357            The profile's membership type.
358        components : `collections.Sequence[aiobungie.ComponentType]`
359            A sequence of components to collect. If the sequence is empty, then all components will be `None`.
360
361        Other Parameters
362        ----------------
363        auth : `str | None`
364            A Bearer access_token to make the request with.
365            This is optional and limited to components that only requires an Authorization token.
366
367        Returns
368        --------
369        `aiobungie.crates.Component`
370            A Destiny 2 player profile with its components.
371            Only passed components will be available if they exists. Otherwise they will be `None`
372
373        Raises
374        ------
375        `aiobungie.MembershipTypeError`
376            The provided membership type was invalid.
377        """
378        data = await self._rest.fetch_profile(member_id, type, components, auth)
379        return self._framework.deserialize_components(data)

Fetch a Bungie profile with the required components.

Example
my_profile_id = 4611686018484639825
my_profile = await client.fetch_profile(
    my_profile_id,
    MembershipType.STEAM,
    components=(ComponentType.CHARACTERS,)
)
characters = my_profile.characters
if characters is not None:
    for character in characters.values():
        print(character.power_level)
Parameters
  • member_id (int): The profile membership's id.
  • type (aiobungie.MembershipType): The profile's membership type.
  • components (collections.Sequence[aiobungie.ComponentType]): A sequence of components to collect. If the sequence is empty, then all components will be None.
Other Parameters
  • auth (str | None): A Bearer access_token to make the request with. This is optional and limited to components that only requires an Authorization token.
Returns
  • aiobungie.crates.Component: A Destiny 2 player profile with its components. Only passed components will be available if they exists. Otherwise they will be None
Raises
async def fetch_linked_profiles( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, all: 'bool' = False) -> 'profile.LinkedProfile':
381    async def fetch_linked_profiles(
382        self,
383        member_id: int,
384        member_type: enums.MembershipType | int,
385        /,
386        *,
387        all: bool = False,
388    ) -> profile.LinkedProfile:
389        """Returns a summary information about all profiles linked to the requested member.
390
391        The passed membership id/type maybe a Bungie.Net membership or a Destiny memberships.
392
393        .. note::
394            It will only return linked accounts whose linkages you are allowed to view.
395
396        Parameters
397        ----------
398        member_id : `int`
399            The ID of the membership. This must be a valid Bungie.Net or PSN or Xbox ID.
400        member_type : `aiobungie.MembershipType`
401            The type for the membership whose linked Destiny account you want to return.
402
403        Other Parameters
404        ----------------
405        all : `bool`
406            If provided and set to `True`, All memberships regardless
407            of whether they're obscured by overrides will be returned,
408
409            If provided and set to `False`, Only available memberships will be returned.
410            The default for this is `False`.
411
412        Returns
413        -------
414        `aiobungie.crates.profile.LinkedProfile`
415            A linked profile object.
416        """
417        resp = await self._rest.fetch_linked_profiles(member_id, member_type, all=all)
418
419        return self._framework.deserialize_linked_profiles(resp)

Returns a summary information about all profiles linked to the requested member.

The passed membership id/type maybe a Bungie.Net membership or a Destiny memberships.

It will only return linked accounts whose linkages you are allowed to view.

Parameters
  • member_id (int): The ID of the membership. This must be a valid Bungie.Net or PSN or Xbox ID.
  • member_type (aiobungie.MembershipType): The type for the membership whose linked Destiny account you want to return.
Other Parameters
  • all (bool): If provided and set to True, All memberships regardless of whether they're obscured by overrides will be returned,

    If provided and set to False, Only available memberships will be returned. The default for this is False.

Returns
async def fetch_membership( self, name: 'str', code: 'int', /, type: 'enums.MembershipType | int' = <MembershipType.ALL: -1>) -> 'collections.Sequence[user.DestinyMembership]':
421    async def fetch_membership(
422        self,
423        name: str,
424        code: int,
425        /,
426        type: enums.MembershipType | int = enums.MembershipType.ALL,
427    ) -> collections.Sequence[user.DestinyMembership]:
428        """Fetch a Destiny 2 player's memberships.
429
430        Parameters
431        -----------
432        name: `str`
433            The unique Bungie player name.
434        code : `int`
435            The unique Bungie display name code.
436        type: `aiobungie.internal.enums.MembershipType`
437            The player's membership type, e,g. XBOX, STEAM, PSN
438
439        Returns
440        --------
441        `collections.Sequence[aiobungie.crates.DestinyMembership]`
442            A sequence of the found Destiny 2 player memberships.
443            An empty sequence will be returned if no one found.
444
445        Raises
446        ------
447        `aiobungie.MembershipTypeError`
448            The provided membership type was invalid.
449        """
450        resp = await self._rest.fetch_membership(name, code, type)
451
452        return self._framework.deserialize_destiny_memberships(resp)

Fetch a Destiny 2 player's memberships.

Parameters
Returns
Raises
async def fetch_character( self, member_id: 'int', membership_type: 'enums.MembershipType | int', character_id: 'int', components: 'collections.Sequence[enums.ComponentType]', auth: 'str | None' = None) -> 'components.CharacterComponent':
454    async def fetch_character(
455        self,
456        member_id: int,
457        membership_type: enums.MembershipType | int,
458        character_id: int,
459        components: collections.Sequence[enums.ComponentType],
460        auth: str | None = None,
461    ) -> components.CharacterComponent:
462        """Fetch a Destiny 2 character.
463
464        Example
465        -------
466        ```py
467        membership_id, titan_id = 0, 0
468        my_character = await client.fetch_character(
469            membership_id,
470            MembershipType.STEAM,
471            titan_id,
472            components=(ComponentType.CHARACTER_INVENTORIES,)
473        )
474        inventory = my_character.inventory
475        if inventory is not None:
476            for item in inventory.values():
477                print(item)
478        ```
479
480        Parameters
481        ----------
482        member_id: `int`
483            A valid bungie member id.
484        character_id: `int`
485            The Destiny character id to retrieve.
486        membership_type: `aiobungie.internal.enums.MembershipType`
487            The member's membership type.
488        components: `collections.Sequence[aiobungie.ComponentType]`
489            Multiple arguments of character components to collect and return.
490
491        Other Parameters
492        ----------------
493        auth : `str | None`
494            A Bearer access_token to make the request with.
495            This is optional and limited to components that only requires an Authorization token.
496
497        Returns
498        -------
499        `aiobungie.crates.CharacterComponent`
500            A Bungie character component.
501
502        `aiobungie.MembershipTypeError`
503            The provided membership type was invalid.
504        """
505        resp = await self._rest.fetch_character(
506            member_id, membership_type, character_id, components, auth
507        )
508
509        return self._framework.deserialize_character_component(resp)

Fetch a Destiny 2 character.

Example
membership_id, titan_id = 0, 0
my_character = await client.fetch_character(
    membership_id,
    MembershipType.STEAM,
    titan_id,
    components=(ComponentType.CHARACTER_INVENTORIES,)
)
inventory = my_character.inventory
if inventory is not None:
    for item in inventory.values():
        print(item)
Parameters
  • member_id (int): A valid bungie member id.
  • character_id (int): The Destiny character id to retrieve.
  • membership_type (aiobungie.internal.enums.MembershipType): The member's membership type.
  • components (collections.Sequence[aiobungie.ComponentType]): Multiple arguments of character components to collect and return.
Other Parameters
  • auth (str | None): A Bearer access_token to make the request with. This is optional and limited to components that only requires an Authorization token.
Returns
async def fetch_unique_weapon_history( self, membership_id: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'collections.Sequence[activity.ExtendedWeaponValues]':
511    async def fetch_unique_weapon_history(
512        self,
513        membership_id: int,
514        character_id: int,
515        membership_type: enums.MembershipType | int,
516    ) -> collections.Sequence[activity.ExtendedWeaponValues]:
517        """Fetch details about unique weapon usage for a character. Includes all exotics.
518
519        Parameters
520        ----------
521        membership_id : `int`
522            The Destiny user membership id.
523        character_id : `int`
524            The character id to retrieve.
525        membership_type : `aiobungie.aiobungie.MembershipType | int`
526            The Destiny user's membership type.
527
528        Returns
529        -------
530        `collections.Sequence[aiobungie.crates.ExtendedWeaponValues]`
531            A sequence of the weapon's extended values.
532        """
533        resp = await self._rest.fetch_unique_weapon_history(
534            membership_id, character_id, membership_type
535        )
536
537        return tuple(
538            self._framework.deserialize_extended_weapon_values(weapon)
539            for weapon in resp["weapons"]
540        )

Fetch details about unique weapon usage for a character. Includes all exotics.

Parameters
  • membership_id (int): The Destiny user membership id.
  • character_id (int): The character id to retrieve.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The Destiny user's membership type.
Returns
async def fetch_activities( self, member_id: 'int', character_id: 'int', mode: 'enums.GameMode | int', membership_type: 'enums.MembershipType | int', *, page: 'int' = 0, limit: 'int' = 250) -> 'sain.Iterator[activity.Activity]':
544    async def fetch_activities(
545        self,
546        member_id: int,
547        character_id: int,
548        mode: enums.GameMode | int,
549        membership_type: enums.MembershipType | int,
550        *,
551        page: int = 0,
552        limit: int = 250,
553    ) -> sain.Iterator[activity.Activity]:
554        """Fetch a Destiny 2 activity for the specified character id.
555
556        Parameters
557        ----------
558        member_id: `int`
559            The user id that starts with `4611`.
560        character_id: `int`
561            The id of the character to retrieve the activities for.
562        mode: `aiobungie.aiobungie.internal.enums.GameMode | int`
563            This parameter filters the game mode, Nightfall, Strike, Iron Banner, etc.
564        membership_type: `aiobungie.internal.enums.MembershipType`
565            The Destiny 2 membership type.
566
567        Other Parameters
568        ----------------
569        page: int
570            The page number. Default is `0`
571        limit: int
572            Limit the returned result. Default is `250`.
573
574        Returns
575        -------
576        `Iterator[aiobungie.crates.Activity]`
577            An iterator of the player's activities.
578
579        Raises
580        ------
581        `aiobungie.MembershipTypeError`
582            The provided membership type was invalid.
583        """
584        resp = await self._rest.fetch_activities(
585            member_id,
586            character_id,
587            mode,
588            membership_type=membership_type,
589            page=page,
590            limit=limit,
591        )
592
593        return self._framework.deserialize_activities(resp)

Fetch a Destiny 2 activity for the specified character id.

Parameters
Other Parameters
  • page (int): The page number. Default is 0
  • limit (int): Limit the returned result. Default is 250.
Returns
Raises
async def fetch_post_activity(self, instance_id: 'int', /) -> 'activity.PostActivity':
595    async def fetch_post_activity(self, instance_id: int, /) -> activity.PostActivity:
596        """Fetch a post activity details.
597
598        Parameters
599        ----------
600        instance_id: `int`
601            The activity instance id.
602
603        Returns
604        -------
605        `aiobungie.crates.PostActivity`
606           A post activity object.
607        """
608        resp = await self._rest.fetch_post_activity(instance_id)
609
610        return self._framework.deserialize_post_activity(resp)

Fetch a post activity details.

Parameters
  • instance_id (int): The activity instance id.
Returns
async def fetch_aggregated_activity_stats( self, character_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'sain.Iterator[activity.AggregatedActivity]':
612    async def fetch_aggregated_activity_stats(
613        self,
614        character_id: int,
615        membership_id: int,
616        membership_type: enums.MembershipType | int,
617    ) -> sain.Iterator[activity.AggregatedActivity]:
618        """Fetch aggregated activity stats for a character.
619
620        Parameters
621        ----------
622        character_id: `int`
623            The id of the character to retrieve the activities for.
624        membership_id: `int`
625            The id of the user that started with `4611`.
626        membership_type: `aiobungie.internal.enums.MembershipType`
627            The Member ship type.
628
629        Returns
630        -------
631        `Iterator[aiobungie.crates.AggregatedActivity]`
632            An iterator of the player's activities.
633
634        Raises
635        ------
636        `aiobungie.MembershipTypeError`
637            The provided membership type was invalid.
638        """
639        resp = await self._rest.fetch_aggregated_activity_stats(
640            character_id, membership_id, membership_type
641        )
642
643        return self._framework.deserialize_aggregated_activities(resp)

Fetch aggregated activity stats for a character.

Parameters
  • character_id (int): The id of the character to retrieve the activities for.
  • membership_id (int): The id of the user that started with 4611.
  • membership_type (aiobungie.internal.enums.MembershipType): The Member ship type.
Returns
Raises
async def fetch_clan_from_id(self, id: 'int', /, access_token: 'str | None' = None) -> 'clans.Clan':
647    async def fetch_clan_from_id(
648        self,
649        id: int,
650        /,
651        access_token: str | None = None,
652    ) -> clans.Clan:
653        """Fetch a Bungie Clan by its id.
654
655        Parameters
656        -----------
657        id: `int`
658            The clan id.
659
660        Returns
661        --------
662        `aiobungie.crates.Clan`
663            An Bungie clan.
664
665        Raises
666        ------
667        `aiobungie.NotFound`
668            The clan was not found.
669        """
670        resp = await self._rest.fetch_clan_from_id(id, access_token)
671
672        return self._framework.deserialize_clan(resp)

Fetch a Bungie Clan by its id.

Parameters
  • id (int): The clan id.
Returns
Raises
async def fetch_clan( self, name: 'str', /, access_token: 'str | None' = None, *, type: 'enums.GroupType | int' = <GroupType.CLAN: 1>) -> 'clans.Clan':
674    async def fetch_clan(
675        self,
676        name: str,
677        /,
678        access_token: str | None = None,
679        *,
680        type: enums.GroupType | int = enums.GroupType.CLAN,
681    ) -> clans.Clan:
682        """Fetch a Clan by its name.
683        This method will return the first clan found with given name.
684
685        Parameters
686        ----------
687        name: `str`
688            The clan name
689
690        Other Parameters
691        ----------------
692        access_token : `str | None`
693            An optional access token to make the request with.
694
695            If the token was bound to a member of the clan,
696            This field `aiobungie.crates.Clan.current_user_membership` will be available
697            and will return the membership of the user who made this request.
698        type : `aiobungie.GroupType`
699            The group type, Default is aiobungie.GroupType.CLAN.
700
701        Returns
702        -------
703        `aiobungie.crates.Clan`
704            A Bungie clan.
705
706        Raises
707        ------
708        `aiobungie.NotFound`
709            The clan was not found.
710        """
711        resp = await self._rest.fetch_clan(name, access_token, type=type)
712
713        return self._framework.deserialize_clan(resp)

Fetch a Clan by its name. This method will return the first clan found with given name.

Parameters
  • name (str): The clan name
Other Parameters
Returns
Raises
async def fetch_clan_conversations( self, clan_id: 'int', /) -> 'collections.Sequence[clans.ClanConversation]':
715    async def fetch_clan_conversations(
716        self, clan_id: int, /
717    ) -> collections.Sequence[clans.ClanConversation]:
718        """Fetch the conversations/chat channels of the given clan id.
719
720        Parameters
721        ----------
722        clan_id : `int`
723            The clan id.
724
725        Returns
726        `collections.Sequence[aiobungie.crates.ClanConversation]`
727            A sequence of the clan chat channels.
728        """
729        resp = await self._rest.fetch_clan_conversations(clan_id)
730
731        return self._framework.deserialize_clan_conversations(resp)

Fetch the conversations/chat channels of the given clan id.

Parameters
async def fetch_clan_admins(self, clan_id: 'int', /) -> 'sain.Iterator[clans.ClanMember]':
733    async def fetch_clan_admins(
734        self, clan_id: int, /
735    ) -> sain.Iterator[clans.ClanMember]:
736        """Fetch the clan founder and admins.
737
738        Parameters
739        ----------
740        clan_id : `int`
741            The clan id.
742
743        Returns
744        -------
745        `aiobungie.Iterator[aiobungie.crates.ClanMember]`
746            An iterator over the found clan admins and founder.
747
748        Raises
749        ------
750        `aiobungie.NotFound`
751            The requested clan was not found.
752        """
753        resp = await self._rest.fetch_clan_admins(clan_id)
754
755        return self._framework.deserialize_clan_members(resp)

Fetch the clan founder and admins.

Parameters
  • clan_id (int): The clan id.
Returns
Raises
async def fetch_groups_for_member( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, filter: 'int' = 0, group_type: 'enums.GroupType' = <GroupType.CLAN: 1>) -> 'collections.Sequence[clans.GroupMember]':
757    async def fetch_groups_for_member(
758        self,
759        member_id: int,
760        member_type: enums.MembershipType | int,
761        /,
762        *,
763        filter: int = 0,
764        group_type: enums.GroupType = enums.GroupType.CLAN,
765    ) -> collections.Sequence[clans.GroupMember]:
766        """Fetch information about the groups that a given member has joined.
767
768        Parameters
769        ----------
770        member_id : `int`
771            The member's id
772        member_type : `aiobungie.MembershipType`
773            The member's membership type.
774
775        Other Parameters
776        ----------------
777        filter : `int`
778            Filter apply to list of joined groups. This Default to `0`
779        group_type : `aiobungie.GroupType`
780            The group's type.
781            This is always set to `aiobungie.GroupType.CLAN` and should not be changed.
782
783        Returns
784        -------
785        `collections.Sequence[aiobungie.crates.GroupMember]`
786            A sequence of joined groups for the fetched member.
787        """
788        resp = await self._rest.fetch_groups_for_member(
789            member_id, member_type, filter=filter, group_type=group_type
790        )
791
792        return tuple(
793            self._framework.deserialize_group_member(group) for group in resp["results"]
794        )

Fetch information about the groups that a given member has joined.

Parameters
Other Parameters
Returns
async def fetch_potential_groups_for_member( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, filter: 'int' = 0, group_type: 'enums.GroupType | int' = <GroupType.CLAN: 1>) -> 'collections.Sequence[clans.GroupMember]':
796    async def fetch_potential_groups_for_member(
797        self,
798        member_id: int,
799        member_type: enums.MembershipType | int,
800        /,
801        *,
802        filter: int = 0,
803        group_type: enums.GroupType | int = enums.GroupType.CLAN,
804    ) -> collections.Sequence[clans.GroupMember]:
805        """Fetch the potential groups for a clan member.
806
807        Parameters
808        ----------
809        member_id : `int`
810            The member's id
811        member_type : `aiobungie.aiobungie.MembershipType | int`
812            The member's membership type.
813
814        Other Parameters
815        ----------------
816        filter : `int`
817            Filter apply to list of joined groups. This Default to `0`
818        group_type : `aiobungie.aiobungie.GroupType | int`
819            The group's type.
820            This is always set to `aiobungie.GroupType.CLAN` and should not be changed.
821
822        Returns
823        -------
824        `collections.Sequence[aiobungie.crates.GroupMember]`
825            A sequence of joined potential groups for the fetched member.
826        """
827        resp = await self._rest.fetch_potential_groups_for_member(
828            member_id, member_type, filter=filter, group_type=group_type
829        )
830
831        return tuple(
832            self._framework.deserialize_group_member(group) for group in resp["results"]
833        )

Fetch the potential groups for a clan member.

Parameters
Other Parameters
Returns
async def fetch_clan_members( self, clan_id: 'int', /, *, name: 'str | None' = None, type: 'enums.MembershipType | int' = <MembershipType.NONE: 0>) -> 'sain.Iterator[clans.ClanMember]':
835    async def fetch_clan_members(
836        self,
837        clan_id: int,
838        /,
839        *,
840        name: str | None = None,
841        type: enums.MembershipType | int = enums.MembershipType.NONE,
842    ) -> sain.Iterator[clans.ClanMember]:
843        """Fetch Bungie clan members.
844
845        Parameters
846        ----------
847        clan_id : `int`
848            The clans id
849
850        Other Parameters
851        ----------------
852        name : `str | None`
853            If provided, Only players matching this name will be returned.
854        type : `aiobungie.MembershipType`
855            An optional clan member's membership type.
856            This parameter is used to filter the returned results
857            by the provided membership, For an example XBox memberships only,
858            Otherwise will return all memberships.
859
860        Returns
861        -------
862        `Iterator[aiobungie.crates.ClanMember]`
863            An iterator over the bungie clan members.
864
865        Raises
866        ------
867        `aiobungie.NotFound`
868            The clan was not found.
869        """
870        resp = await self._rest.fetch_clan_members(clan_id, type=type, name=name)
871
872        return self._framework.deserialize_clan_members(resp)

Fetch Bungie clan members.

Parameters
  • clan_id (int): The clans id
Other Parameters
  • name (str | None): If provided, Only players matching this name will be returned.
  • type (aiobungie.MembershipType): An optional clan member's membership type. This parameter is used to filter the returned results by the provided membership, For an example XBox memberships only, Otherwise will return all memberships.
Returns
Raises
async def fetch_clan_banners(self) -> 'collections.Sequence[clans.ClanBanner]':
874    async def fetch_clan_banners(self) -> collections.Sequence[clans.ClanBanner]:
875        """Fetch the clan banners.
876
877        Returns
878        -------
879        `collections.Sequence[aiobungie.crates.ClanBanner]`
880            A sequence of the clan banners.
881        """
882        resp = await self._rest.fetch_clan_banners()
883
884        return self._framework.deserialize_clan_banners(resp)

Fetch the clan banners.

Returns
async def kick_clan_member( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'clans.Clan':
887    async def kick_clan_member(
888        self,
889        access_token: str,
890        /,
891        group_id: int,
892        membership_id: int,
893        membership_type: enums.MembershipType | int,
894    ) -> clans.Clan:
895        """Kick a member from the clan.
896
897        .. note::
898            This request requires OAuth2: oauth2: `AdminGroups` scope.
899
900        Parameters
901        ----------
902        access_token : `str`
903            The bearer access token associated with the bungie account.
904        group_id: `int`
905            The group id.
906        membership_id : `int`
907            The member id to kick.
908        membership_type : `aiobungie.aiobungie.MembershipType | int`
909            The member's membership type.
910
911        Returns
912        -------
913        `aiobungie.crates.clan.Clan`
914            The clan that the member was kicked from.
915        """
916        resp = await self._rest.kick_clan_member(
917            access_token,
918            group_id=group_id,
919            membership_id=membership_id,
920            membership_type=membership_type,
921        )
922
923        return self._framework.deserialize_clan(resp)

Kick a member from the clan.

This request requires OAuth2: oauth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id.
  • membership_id (int): The member id to kick.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The member's membership type.
Returns
async def fetch_clan_weekly_rewards(self, clan_id: 'int') -> 'milestones.Milestone':
925    async def fetch_clan_weekly_rewards(self, clan_id: int) -> milestones.Milestone:
926        """Fetch a Bungie clan's weekly reward state.
927
928        Parameters
929        ----------
930        clan_id : `int`
931            The clan's id.
932
933        Returns
934        -------
935        `aiobungie.crates.Milestone`
936            A runtime status of the clan's milestone data.
937        """
938
939        resp = await self._rest.fetch_clan_weekly_rewards(clan_id)
940
941        return self._framework.deserialize_milestone(resp)

Fetch a Bungie clan's weekly reward state.

Parameters
  • clan_id (int): The clan's id.
Returns
async def search_group( self, name: 'str', group_type: 'enums.GroupType | int', *, creation_date: 'clans.GroupDate | int' = 0, sort_by: 'int | None' = None, group_member_count_filter: 'typing.Literal[0, 1, 2, 3] | None' = None, locale_filter: 'str | None' = None, tag_text: 'str | None' = None, items_per_page: 'int | None' = None, current_page: 'int | None' = None, request_token: 'str | None' = None) -> 'collections.Sequence[clans.Group]':
 943    async def search_group(
 944        self,
 945        name: str,
 946        group_type: enums.GroupType | int,
 947        *,
 948        creation_date: clans.GroupDate | int = 0,
 949        sort_by: int | None = None,
 950        group_member_count_filter: typing.Literal[0, 1, 2, 3] | None = None,
 951        locale_filter: str | None = None,
 952        tag_text: str | None = None,
 953        items_per_page: int | None = None,
 954        current_page: int | None = None,
 955        request_token: str | None = None,
 956    ) -> collections.Sequence[clans.Group]:
 957        """Search for groups.
 958
 959        .. note::
 960            If the group type is set to `CLAN`, then parameters `group_member_count_filter`,
 961            `locale_filter` and `tag_text` must be `None`, otherwise `ValueError` will be raised.
 962
 963        Parameters
 964        ----------
 965        name : `str`
 966            The group name.
 967        group_type : `aiobungie.GroupType | int`
 968            The group type that's being searched for.
 969
 970        Other Parameters
 971        ----------------
 972        creation_date : `aiobungie.GroupDate | int`
 973            The creation date of the group. Defaults to `0` which is all time.
 974        sort_by : `int | None`
 975            ...
 976        group_member_count_filter : `int | None`
 977            ...
 978        locale_filter : `str | None`
 979            ...
 980        tag_text : `str | None`
 981            ...
 982        items_per_page : `int | None`
 983            ...
 984        current_page : `int | None`
 985            ...
 986        request_token : `str | None`
 987            ...
 988
 989        Returns
 990        --------
 991        `collections.Sequence[aiobungie.crates.Group]`
 992            An array that contains the groups that match the search criteria.
 993
 994        Raises
 995        ------
 996        `ValueError`
 997            If the group type is `aiobungie.GroupType.CLAN` and `group_member_count_filter`,
 998            `locale_filter` and `tag_text` are not `None`.
 999        """
1000        response = await self._rest.search_group(
1001            name,
1002            group_type,
1003            sort_by=sort_by,
1004            creation_date=creation_date,
1005            group_member_count_filter=group_member_count_filter,
1006            locale_filter=locale_filter,
1007            tag_text=tag_text,
1008            items_per_page=items_per_page,
1009            current_page=current_page,
1010            request_token=request_token,
1011        )
1012        return tuple(
1013            self._framework.deserialize_group(result) for result in response["results"]
1014        )

Search for groups.

If the group type is set to CLAN, then parameters group_member_count_filter, locale_filter and tag_text must be None, otherwise ValueError will be raised.

Parameters
  • name (str): The group name.
  • group_type (aiobungie.GroupType | int): The group type that's being searched for.
Other Parameters
  • creation_date (aiobungie.GroupDate | int): The creation date of the group. Defaults to 0 which is all time.
  • sort_by (int | None): ...
  • group_member_count_filter (int | None): ...
  • locale_filter (str | None): ...
  • tag_text (str | None): ...
  • items_per_page (int | None): ...
  • current_page (int | None): ...
  • request_token (str | None): ...
Returns
  • collections.Sequence[aiobungie.crates.Group]: An array that contains the groups that match the search criteria.
Raises
  • ValueError: If the group type is aiobungie.GroupType.CLAN and group_member_count_filter, locale_filter and tag_text are not None.
async def fetch_inventory_item(self, hash: 'int', /) -> 'entity.InventoryEntity':
1018    async def fetch_inventory_item(self, hash: int, /) -> entity.InventoryEntity:
1019        """Fetch a static inventory item entity given a its hash.
1020
1021        Parameters
1022        ----------
1023        hash: `int`
1024            Inventory item's hash.
1025
1026        Returns
1027        -------
1028        `aiobungie.crates.InventoryEntity`
1029            A bungie inventory item.
1030        """
1031        resp = await self._rest.fetch_inventory_item(hash)
1032
1033        return self._framework.deserialize_inventory_entity(resp)

Fetch a static inventory item entity given a its hash.

Parameters
  • hash (int): Inventory item's hash.
Returns
async def fetch_objective_entity(self, hash: 'int', /) -> 'entity.ObjectiveEntity':
1035    async def fetch_objective_entity(self, hash: int, /) -> entity.ObjectiveEntity:
1036        """Fetch a Destiny objective entity given a its hash.
1037
1038        Parameters
1039        ----------
1040        hash: `int`
1041            objective's hash.
1042
1043        Returns
1044        -------
1045        `aiobungie.crates.ObjectiveEntity`
1046            An objective entity item.
1047        """
1048        resp = await self._rest.fetch_objective_entity(hash)
1049
1050        return self._framework.deserialize_objective_entity(resp)

Fetch a Destiny objective entity given a its hash.

Parameters
  • hash (int): objective's hash.
Returns
@helpers.unstable
async def search_entities( self, name: 'str', entity_type: 'str', *, page: 'int' = 0) -> 'sain.Iterator[entity.SearchableEntity]':
1052    @helpers.unstable
1053    async def search_entities(
1054        self, name: str, entity_type: str, *, page: int = 0
1055    ) -> sain.Iterator[entity.SearchableEntity]:
1056        """Search for Destiny2 entities given a name and its type.
1057
1058        Parameters
1059        ----------
1060        name : `str`
1061            The name of the entity, i.e., Thunderlord, One thousand voices.
1062        entity_type : `str`
1063            The type of the entity, AKA Definition,
1064            For an example `DestinyInventoryItemDefinition` for emblems, weapons, and other inventory items.
1065
1066        Other Parameters
1067        ----------------
1068        page : `int`
1069            An optional page to return. Default to 0.
1070
1071        Returns
1072        -------
1073        `Iterator[aiobungie.crates.SearchableEntity]`
1074            An iterator over the found results matching the provided name.
1075        """
1076        # resp = await self._rest.search_entities(name, entity_type, page=page)
1077        # calling this method will raise anyways.
1078        raise

Search for Destiny2 entities given a name and its type.

Parameters
  • name (str): The name of the entity, i.e., Thunderlord, One thousand voices.
  • entity_type (str): The type of the entity, AKA Definition, For an example DestinyInventoryItemDefinition for emblems, weapons, and other inventory items.
Other Parameters
  • page (int): An optional page to return. Default to 0.
Returns
@helpers.unstable
async def fetch_fireteams( self, activity_type: 'fireteams.FireteamActivity | int', *, platform: 'fireteams.FireteamPlatform | int' = <FireteamPlatform.ANY: 0>, language: 'fireteams.FireteamLanguage | str' = <FireteamLanguage.ALL: >, date_range: 'int' = 0, page: 'int' = 0, slots_filter: 'int' = 0) -> 'collections.Sequence[fireteams.Fireteam]':
1082    @helpers.unstable
1083    async def fetch_fireteams(
1084        self,
1085        activity_type: fireteams.FireteamActivity | int,
1086        *,
1087        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1088        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1089        date_range: int = 0,
1090        page: int = 0,
1091        slots_filter: int = 0,
1092    ) -> collections.Sequence[fireteams.Fireteam]:
1093        """Fetch public Bungie fireteams with open slots.
1094
1095        Parameters
1096        ----------
1097        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1098            The fireteam activity type.
1099
1100        Other Parameters
1101        ----------------
1102        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1103            If this is provided. Then the results will be filtered with the given platform.
1104            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1105        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1106            A locale language to filter the used language in that fireteam.
1107            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1108        date_range : `int`
1109            An integer to filter the date range of the returned fireteams. Defaults to `aiobungie.FireteamDate.ALL`.
1110        page : `int`
1111            The page number. By default its `0` which returns all available activities.
1112        slots_filter : `int`
1113            Filter the returned fireteams based on available slots. Default is `0`
1114
1115        Returns
1116        -------
1117        `collections.Sequence[fireteams.Fireteam]`
1118            A sequence of `aiobungie.crates.Fireteam`.
1119        """
1120
1121        # resp = await self._rest.fetch_fireteams(
1122        #     activity_type,
1123        #     platform=platform,
1124        #     language=language,
1125        #     date_range=date_range,
1126        #     page=page,
1127        #     slots_filter=slots_filter,
1128        # )
1129
1130        # return self._framework.deserialize_fireteams(resp)
1131        # ! unreachable
1132        raise

Fetch public Bungie fireteams with open slots.

Parameters
Other Parameters
Returns
async def fetch_available_clan_fireteams( self, access_token: 'str', group_id: 'int', activity_type: 'fireteams.FireteamActivity | int', *, platform: 'fireteams.FireteamPlatform | int', language: 'fireteams.FireteamLanguage | str', date_range: 'int' = 0, page: 'int' = 0, public_only: 'bool' = False, slots_filter: 'int' = 0) -> 'collections.Sequence[fireteams.Fireteam]':
1134    async def fetch_available_clan_fireteams(
1135        self,
1136        access_token: str,
1137        group_id: int,
1138        activity_type: fireteams.FireteamActivity | int,
1139        *,
1140        platform: fireteams.FireteamPlatform | int,
1141        language: fireteams.FireteamLanguage | str,
1142        date_range: int = 0,
1143        page: int = 0,
1144        public_only: bool = False,
1145        slots_filter: int = 0,
1146    ) -> collections.Sequence[fireteams.Fireteam]:
1147        """Fetch a clan's fireteams with open slots.
1148
1149        .. note::
1150            This method requires OAuth2: ReadGroups scope.
1151
1152        Parameters
1153        ----------
1154        access_token : `str`
1155            The bearer access token associated with the bungie account.
1156        group_id : `int`
1157            The group/clan id of the fireteam.
1158        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1159            The fireteam activity type.
1160
1161        Other Parameters
1162        ----------------
1163        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1164            If this is provided. Then the results will be filtered with the given platform.
1165            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1166        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1167            A locale language to filter the used language in that fireteam.
1168            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1169        date_range : `int`
1170            An integer to filter the date range of the returned fireteams. Defaults to `0`.
1171        page : `int`
1172            The page number. By default its `0` which returns all available activities.
1173        public_only: `bool`
1174            If set to True, Then only public fireteams will be returned.
1175        slots_filter : `int`
1176            Filter the returned fireteams based on available slots. Default is `0`
1177
1178        Returns
1179        -------
1180        `collections.Sequence[aiobungie.crates.Fireteam]`
1181            A sequence of  fireteams found in the clan.
1182            `None` will be returned if nothing was found.
1183        """
1184        resp = await self._rest.fetch_available_clan_fireteams(
1185            access_token,
1186            group_id,
1187            activity_type,
1188            platform=platform,
1189            language=language,
1190            date_range=date_range,
1191            page=page,
1192            public_only=public_only,
1193            slots_filter=slots_filter,
1194        )
1195
1196        return self._framework.deserialize_fireteams(resp)

Fetch a clan's fireteams with open slots.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id of the fireteam.
  • activity_type (aiobungie.aiobungie.crates.FireteamActivity | int): The fireteam activity type.
Other Parameters
Returns
  • collections.Sequence[aiobungie.crates.Fireteam]: A sequence of fireteams found in the clan. None will be returned if nothing was found.
async def fetch_clan_fireteam( self, access_token: 'str', fireteam_id: 'int', group_id: 'int') -> 'fireteams.AvailableFireteam':
1198    async def fetch_clan_fireteam(
1199        self, access_token: str, fireteam_id: int, group_id: int
1200    ) -> fireteams.AvailableFireteam:
1201        """Fetch a specific clan fireteam.
1202
1203        .. note::
1204            This method requires OAuth2: ReadGroups scope.
1205
1206        Parameters
1207        ----------
1208        access_token : `str`
1209            The bearer access token associated with the bungie account.
1210        group_id : `int`
1211            The group/clan id to fetch the fireteam from.
1212        fireteam_id : `int`
1213            The fireteam id to fetch.
1214
1215        Returns
1216        -------
1217        `aiobungie.crates.AvailableFireteam`
1218            A sequence of available fireteams objects.
1219        """
1220        resp = await self._rest.fetch_clan_fireteam(access_token, fireteam_id, group_id)
1221
1222        return self._framework.deserialize_available_fireteam(resp)

Fetch a specific clan fireteam.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id to fetch the fireteam from.
  • fireteam_id (int): The fireteam id to fetch.
Returns
async def fetch_my_clan_fireteams( self, access_token: 'str', group_id: 'int', *, include_closed: 'bool' = True, platform: 'fireteams.FireteamPlatform | int', language: 'fireteams.FireteamLanguage | str', filtered: 'bool' = True, page: 'int' = 0) -> 'collections.Sequence[fireteams.AvailableFireteam]':
1224    async def fetch_my_clan_fireteams(
1225        self,
1226        access_token: str,
1227        group_id: int,
1228        *,
1229        include_closed: bool = True,
1230        platform: fireteams.FireteamPlatform | int,
1231        language: fireteams.FireteamLanguage | str,
1232        filtered: bool = True,
1233        page: int = 0,
1234    ) -> collections.Sequence[fireteams.AvailableFireteam]:
1235        """A method that's similar to `fetch_fireteams` but requires OAuth2.
1236
1237        .. note::
1238            This method requires OAuth2: ReadGroups scope.
1239
1240        Parameters
1241        ----------
1242        access_token : str
1243            The bearer access token associated with the bungie account.
1244        group_id : int
1245            The group/clan id to fetch.
1246
1247        Other Parameters
1248        ----------------
1249        include_closed : `bool`
1250            If provided and set to True, It will also return closed fireteams.
1251            If provided and set to False, It will only return public fireteams. Default is True.
1252        platform : aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int
1253            If this is provided. Then the results will be filtered with the given platform.
1254            Defaults to aiobungie.crates.FireteamPlatform.ANY which returns all platforms.
1255        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1256            A locale language to filter the used language in that fireteam.
1257            Defaults to aiobungie.crates.FireteamLanguage.ALL
1258        filtered : `bool`
1259            If set to True, it will filter by clan. Otherwise not. Default is True.
1260        page : `int`
1261            The page number. By default its 0 which returns all available activities.
1262
1263        Returns
1264        -------
1265        `collections.Sequence[aiobungie.crates.AvailableFireteam]`
1266            A sequence of available fireteams objects if exists. else `None` will be returned.
1267        """
1268        resp = await self._rest.fetch_my_clan_fireteams(
1269            access_token,
1270            group_id,
1271            include_closed=include_closed,
1272            platform=platform,
1273            language=language,
1274            filtered=filtered,
1275            page=page,
1276        )
1277
1278        return self._framework.deserialize_available_fireteams(resp)

A method that's similar to fetch_fireteams but requires OAuth2.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id to fetch.
Other Parameters
Returns
async def fetch_friends(self, access_token: 'str', /) -> 'collections.Sequence[friends.Friend]':
1282    async def fetch_friends(
1283        self, access_token: str, /
1284    ) -> collections.Sequence[friends.Friend]:
1285        """Fetch bungie friend list.
1286
1287        .. note::
1288            This requests OAuth2: ReadUserData scope.
1289
1290        Parameters
1291        -----------
1292        access_token : `str`
1293            The bearer access token associated with the bungie account.
1294
1295        Returns
1296        -------
1297        `collections.Sequence[aiobungie.crates.Friend]`
1298            A sequence of the friends associated with that access token.
1299        """
1300
1301        resp = await self._rest.fetch_friends(access_token)
1302
1303        return self._framework.deserialize_friends(resp)

Fetch bungie friend list.

This requests OAuth2: ReadUserData scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
Returns
async def fetch_friend_requests(self, access_token: 'str', /) -> 'friends.FriendRequestView':
1305    async def fetch_friend_requests(
1306        self, access_token: str, /
1307    ) -> friends.FriendRequestView:
1308        """Fetch pending bungie friend requests queue.
1309
1310        .. note::
1311            This requests OAuth2: ReadUserData scope.
1312
1313        Parameters
1314        -----------
1315        access_token : `str`
1316            The bearer access token associated with the bungie account.
1317
1318        Returns
1319        -------
1320        `aiobungie.crates.FriendRequestView`
1321            A friend requests view of that associated access token.
1322        """
1323
1324        resp = await self._rest.fetch_friend_requests(access_token)
1325
1326        return self._framework.deserialize_friend_requests(resp)

Fetch pending bungie friend requests queue.

This requests OAuth2: ReadUserData scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
Returns
async def fetch_application(self, appid: 'int', /) -> 'application.Application':
1330    async def fetch_application(self, appid: int, /) -> application.Application:
1331        """Fetch a Bungie application.
1332
1333        Parameters
1334        -----------
1335        appid: `int`
1336            The application id.
1337
1338        Returns
1339        --------
1340        `aiobungie.crates.Application`
1341            A Bungie application.
1342        """
1343        resp = await self._rest.fetch_application(appid)
1344
1345        return self._framework.deserialize_application(resp)

Fetch a Bungie application.

Parameters
  • appid (int): The application id.
Returns
async def fetch_public_milestone_content(self, milestone_hash: 'int', /) -> 'milestones.MilestoneContent':
1349    async def fetch_public_milestone_content(
1350        self, milestone_hash: int, /
1351    ) -> milestones.MilestoneContent:
1352        """Fetch the milestone content given its hash.
1353
1354        Parameters
1355        ----------
1356        milestone_hash : `int`
1357            The milestone hash.
1358
1359        Returns
1360        -------
1361        `aiobungie.crates.milestones.MilestoneContent`
1362            A milestone content object.
1363        """
1364        ...
1365        resp = await self._rest.fetch_public_milestone_content(milestone_hash)
1366        return self._framework.deserialize_public_milestone_content(resp)

Fetch the milestone content given its hash.

Parameters
  • milestone_hash (int): The milestone hash.
Returns
@typing.final
class ClosedReasons(aiobungie.Flag):
774@typing.final
775class ClosedReasons(Flag):
776    """A Flags enumeration representing the reasons why a person can't join this user's fireteam."""
777
778    NONE = 0
779    MATCHMAKING = 1 << 0
780    LOADING = 1 << 1
781    SOLO = 1 << 2
782    """The activity is required to be played solo."""
783    INTERNAL_REASONS = 1 << 3
784    """
785    The user can't be joined for one of a variety of internal reasons.
786    Basically, the game can't let you join at this time,
787    but for reasons that aren't under the control of this user
788    """
789    DISALLOWED_BY_GAME_STATE = 1 << 4
790    """The user's current activity/quest/other transitory game state is preventing joining."""
791    OFFLINE = 32768
792    """The user appears offline."""

A Flags enumeration representing the reasons why a person can't join this user's fireteam.

NONE = <ClosedReasons.NONE: 0>
MATCHMAKING = <ClosedReasons.MATCHMAKING: 1>
LOADING = <ClosedReasons.LOADING: 2>
SOLO = <ClosedReasons.SOLO: 4>

The activity is required to be played solo.

INTERNAL_REASONS = <ClosedReasons.INTERNAL_REASONS: 8>

The user can't be joined for one of a variety of internal reasons. Basically, the game can't let you join at this time, but for reasons that aren't under the control of this user

DISALLOWED_BY_GAME_STATE = <ClosedReasons.DISALLOWED_BY_GAME_STATE: 16>

The user's current activity/quest/other transitory game state is preventing joining.

OFFLINE = <ClosedReasons.OFFLINE: 32768>

The user appears offline.

Inherited Members
Flag
name
value
@typing.final
class ComponentPrivacy(builtins.int, aiobungie.Enum):
60@typing.final
61class ComponentPrivacy(int, enums.Enum):
62    """An enum the provides privacy settings for profile components."""
63
64    NONE = 0
65    PUBLIC = 1
66    PRIVATE = 2

An enum the provides privacy settings for profile components.

NONE = <ComponentPrivacy.NONE: 0>
PUBLIC = <ComponentPrivacy.PUBLIC: 1>
PRIVATE = <ComponentPrivacy.PRIVATE: 2>
Inherited Members
Enum
name
value
@typing.final
class ComponentType(aiobungie.Enum):
349@typing.final
350class ComponentType(Enum):
351    """An Enum for Destiny 2 profile Components."""
352
353    NONE = 0
354
355    PROFILE = 100
356    PROFILE_INVENTORIES = 102
357    PROFILE_CURRENCIES = 103
358    PROFILE_PROGRESSION = 104
359    ALL_PROFILES = (
360        PROFILE,
361        PROFILE_INVENTORIES,
362        PROFILE_CURRENCIES,
363        PROFILE_PROGRESSION,
364    )
365    """All profile components."""
366
367    VENDORS = 400
368    VENDOR_SALES = 402
369    VENDOR_RECEIPTS = 101
370    ALL_VENDORS = (VENDORS, VENDOR_RECEIPTS, VENDOR_SALES)
371    """All vendor components."""
372
373    # Items
374    ITEM_INSTANCES = 300
375    ITEM_OBJECTIVES = 301
376    ITEM_PERKS = 302
377    ITEM_RENDER_DATA = 303
378    ITEM_STATS = 304
379    ITEM_SOCKETS = 305
380    ITEM_TALENT_GRINDS = 306
381    ITEM_PLUG_STATES = 308
382    ITEM_PLUG_OBJECTIVES = 309
383    ITEM_REUSABLE_PLUGS = 310
384
385    ALL_ITEMS = (
386        ITEM_PLUG_OBJECTIVES,
387        ITEM_PLUG_STATES,
388        ITEM_SOCKETS,
389        ITEM_INSTANCES,
390        ITEM_OBJECTIVES,
391        ITEM_PERKS,
392        ITEM_RENDER_DATA,
393        ITEM_STATS,
394        ITEM_TALENT_GRINDS,
395        ITEM_REUSABLE_PLUGS,
396    )
397    """All item components."""
398
399    PLATFORM_SILVER = 105
400    KIOSKS = 500
401    CURRENCY_LOOKUPS = 600
402    PRESENTATION_NODES = 700
403    COLLECTIBLES = 800
404    RECORDS = 900
405    TRANSITORY = 1000
406    METRICS = 1100
407    INVENTORIES = 102
408    STRING_VARIABLES = 1200
409    CRAFTABLES = 1300
410    SOCIAL_COMMENDATIONS = 1400
411
412    CHARACTERS = 200
413    CHARACTER_INVENTORY = 201
414    CHARACTER_PROGRESSION = 202
415    CHARACTER_RENDER_DATA = 203
416    CHARACTER_ACTIVITIES = 204
417    CHARACTER_EQUIPMENT = 205
418    CHARACTER_LOADOUTS = 206
419
420    ALL_CHARACTERS = (
421        CHARACTERS,
422        CHARACTER_INVENTORY,
423        CHARACTER_PROGRESSION,
424        CHARACTER_RENDER_DATA,
425        CHARACTER_ACTIVITIES,
426        CHARACTER_EQUIPMENT,
427        CHARACTER_LOADOUTS,
428        RECORDS,
429    )
430    """All character components."""
431
432    ALL = (
433        *ALL_PROFILES,
434        *ALL_CHARACTERS,
435        *ALL_VENDORS,
436        *ALL_ITEMS,
437        RECORDS,
438        CURRENCY_LOOKUPS,
439        PRESENTATION_NODES,
440        COLLECTIBLES,
441        KIOSKS,
442        METRICS,
443        PLATFORM_SILVER,
444        INVENTORIES,
445        STRING_VARIABLES,
446        TRANSITORY,
447        CRAFTABLES,
448        SOCIAL_COMMENDATIONS,
449    )
450    """All components included."""

An Enum for Destiny 2 profile Components.

NONE = <ComponentType.NONE: 0>
PROFILE = <ComponentType.PROFILE: 100>
PROFILE_INVENTORIES = <ComponentType.PROFILE_INVENTORIES: 102>
PROFILE_CURRENCIES = <ComponentType.PROFILE_CURRENCIES: 103>
PROFILE_PROGRESSION = <ComponentType.PROFILE_PROGRESSION: 104>
ALL_PROFILES = <ComponentType.ALL_PROFILES: (100, 102, 103, 104)>

All profile components.

VENDORS = <ComponentType.VENDORS: 400>
VENDOR_SALES = <ComponentType.VENDOR_SALES: 402>
VENDOR_RECEIPTS = <ComponentType.VENDOR_RECEIPTS: 101>
ALL_VENDORS = <ComponentType.ALL_VENDORS: (400, 101, 402)>

All vendor components.

ITEM_INSTANCES = <ComponentType.ITEM_INSTANCES: 300>
ITEM_OBJECTIVES = <ComponentType.ITEM_OBJECTIVES: 301>
ITEM_PERKS = <ComponentType.ITEM_PERKS: 302>
ITEM_RENDER_DATA = <ComponentType.ITEM_RENDER_DATA: 303>
ITEM_STATS = <ComponentType.ITEM_STATS: 304>
ITEM_SOCKETS = <ComponentType.ITEM_SOCKETS: 305>
ITEM_TALENT_GRINDS = <ComponentType.ITEM_TALENT_GRINDS: 306>
ITEM_PLUG_STATES = <ComponentType.ITEM_PLUG_STATES: 308>
ITEM_PLUG_OBJECTIVES = <ComponentType.ITEM_PLUG_OBJECTIVES: 309>
ITEM_REUSABLE_PLUGS = <ComponentType.ITEM_REUSABLE_PLUGS: 310>
ALL_ITEMS = <ComponentType.ALL_ITEMS: (309, 308, 305, 300, 301, 302, 303, 304, 306, 310)>

All item components.

PLATFORM_SILVER = <ComponentType.PLATFORM_SILVER: 105>
KIOSKS = <ComponentType.KIOSKS: 500>
CURRENCY_LOOKUPS = <ComponentType.CURRENCY_LOOKUPS: 600>
PRESENTATION_NODES = <ComponentType.PRESENTATION_NODES: 700>
COLLECTIBLES = <ComponentType.COLLECTIBLES: 800>
RECORDS = <ComponentType.RECORDS: 900>
TRANSITORY = <ComponentType.TRANSITORY: 1000>
METRICS = <ComponentType.METRICS: 1100>
INVENTORIES = <ComponentType.PROFILE_INVENTORIES: 102>
STRING_VARIABLES = <ComponentType.STRING_VARIABLES: 1200>
CRAFTABLES = <ComponentType.CRAFTABLES: 1300>
SOCIAL_COMMENDATIONS = <ComponentType.SOCIAL_COMMENDATIONS: 1400>
CHARACTERS = <ComponentType.CHARACTERS: 200>
CHARACTER_INVENTORY = <ComponentType.CHARACTER_INVENTORY: 201>
CHARACTER_PROGRESSION = <ComponentType.CHARACTER_PROGRESSION: 202>
CHARACTER_RENDER_DATA = <ComponentType.CHARACTER_RENDER_DATA: 203>
CHARACTER_ACTIVITIES = <ComponentType.CHARACTER_ACTIVITIES: 204>
CHARACTER_EQUIPMENT = <ComponentType.CHARACTER_EQUIPMENT: 205>
CHARACTER_LOADOUTS = <ComponentType.CHARACTER_LOADOUTS: 206>
ALL_CHARACTERS = <ComponentType.ALL_CHARACTERS: (200, 201, 202, 203, 204, 205, 206, 900)>

All character components.

ALL = <ComponentType.ALL: (100, 102, 103, 104, 200, 201, 202, 203, 204, 205, 206, 900, 400, 101, 402, 309, 308, 305, 300, 301, 302, 303, 304, 306, 310, 900, 600, 700, 800, 500, 1100, 105, 102, 1200, 1000, 1300, 1400)>

All components included.

Inherited Members
Enum
name
value
@typing.final
class CredentialType(builtins.int, aiobungie.Enum):
656@typing.final
657class CredentialType(int, Enum):
658    """The types of the accounts system supports at bungie."""
659
660    NONE = 0
661    XUID = 1
662    PSNID = 2
663    WILD = 3
664    FAKE = 4
665    FACEBOOK = 5
666    GOOGLE = 8
667    WINDOWS = 9
668    DEMONID = 10
669    STEAMID = 12
670    BATTLENETID = 14
671    STADIAID = 16
672    TWITCHID = 18

The types of the accounts system supports at bungie.

NONE = <CredentialType.NONE: 0>
XUID = <CredentialType.XUID: 1>
PSNID = <CredentialType.PSNID: 2>
WILD = <CredentialType.WILD: 3>
FAKE = <CredentialType.FAKE: 4>
FACEBOOK = <CredentialType.FACEBOOK: 5>
GOOGLE = <CredentialType.GOOGLE: 8>
WINDOWS = <CredentialType.WINDOWS: 9>
DEMONID = <CredentialType.DEMONID: 10>
STEAMID = <CredentialType.STEAMID: 12>
BATTLENETID = <CredentialType.BATTLENETID: 14>
STADIAID = <CredentialType.STADIAID: 16>
TWITCHID = <CredentialType.TWITCHID: 18>
Inherited Members
Enum
name
value
@typing.final
class DamageType(builtins.int, aiobungie.Enum):
534@typing.final
535class DamageType(int, Enum):
536    """Enums for Destiny Damage types"""
537
538    NONE = 0
539    KINETIC = 1
540    ARC = 2
541    SOLAR = 3
542    VOID = 4
543    RAID = 5
544    """This is a special damage type reserved for some raid activity encounters."""
545    STASIS = 6

Enums for Destiny Damage types

NONE = <DamageType.NONE: 0>
KINETIC = <DamageType.KINETIC: 1>
ARC = <DamageType.ARC: 2>
SOLAR = <DamageType.SOLAR: 3>
VOID = <DamageType.VOID: 4>
RAID = <DamageType.RAID: 5>

This is a special damage type reserved for some raid activity encounters.

STASIS = <DamageType.STASIS: 6>
Inherited Members
Enum
name
value
@typing.final
class Difficulty(builtins.int, aiobungie.Enum):
60@typing.final
61class Difficulty(int, enums.Enum):
62    """An enum for activities difficulties."""
63
64    TRIVIAL = 0
65    EASY = 1
66    NORMAL = 2
67    CHALLENGING = 3
68    HARD = 4
69    BRAVE = 5
70    ALMOST_IMPOSSIBLE = 6
71    IMPOSSIBLE = 7

An enum for activities difficulties.

TRIVIAL = <Difficulty.TRIVIAL: 0>
EASY = <Difficulty.EASY: 1>
NORMAL = <Difficulty.NORMAL: 2>
CHALLENGING = <Difficulty.CHALLENGING: 3>
HARD = <Difficulty.HARD: 4>
BRAVE = <Difficulty.BRAVE: 5>
ALMOST_IMPOSSIBLE = <Difficulty.ALMOST_IMPOSSIBLE: 6>
IMPOSSIBLE = <Difficulty.IMPOSSIBLE: 7>
Inherited Members
Enum
name
value
@typing.final
class Dungeon(builtins.int, aiobungie.Enum):
151@typing.final
152class Dungeon(int, Enum):
153    """An Enum for all available Dungeon/Like missions in Destiny 2."""
154
155    NORMAL_PRESAGE = 2124066889
156    """Normal Presage"""
157
158    MASTER_PRESAGE = 4212753278
159    """Master Presage"""
160
161    HARBINGER = 1738383283
162    """Harbinger"""
163
164    PROPHECY = 4148187374
165    """Prophecy"""
166
167    MASTER_POH = 785700673
168    """Master Pit of Heresy?"""
169
170    LEGEND_POH = 785700678
171    """Legend Pit of Heresy?"""
172
173    POH = 1375089621
174    """Normal Pit of Heresy."""
175
176    SHATTERED = 2032534090
177    """Shattered Throne"""
178
179    GOA_LEGEND = 4078656646
180    """Grasp of Avarice legend."""
181
182    GOA_MASTER = 3774021532
183    """Grasp of Avarice master."""

An Enum for all available Dungeon/Like missions in Destiny 2.

NORMAL_PRESAGE = <Dungeon.NORMAL_PRESAGE: 2124066889>

Normal Presage

MASTER_PRESAGE = <Dungeon.MASTER_PRESAGE: 4212753278>

Master Presage

HARBINGER = <Dungeon.HARBINGER: 1738383283>

Harbinger

PROPHECY = <Dungeon.PROPHECY: 4148187374>

Prophecy

MASTER_POH = <Dungeon.MASTER_POH: 785700673>

Master Pit of Heresy?

LEGEND_POH = <Dungeon.LEGEND_POH: 785700678>

Legend Pit of Heresy?

POH = <Dungeon.POH: 1375089621>

Normal Pit of Heresy.

SHATTERED = <Dungeon.SHATTERED: 2032534090>

Shattered Throne

GOA_LEGEND = <Dungeon.GOA_LEGEND: 4078656646>

Grasp of Avarice legend.

GOA_MASTER = <Dungeon.GOA_MASTER: 3774021532>

Grasp of Avarice master.

Inherited Members
Enum
name
value
class Enum(enum.Enum):
71class Enum(__enum.Enum):
72    """Builtin Python enum with extra handlings."""
73
74    @property
75    def name(self) -> str:
76        return self._name_
77
78    @property
79    def value(self) -> typing.Any:
80        return self._value_
81
82    def __str__(self) -> str:
83        return self._name_
84
85    def __repr__(self) -> str:
86        return f"<{type(self).__name__}.{self._name_}: {self._value_!s}>"
87
88    def __int__(self) -> int:
89        return int(self.value)

Builtin Python enum with extra handlings.

name: 'str'
74    @property
75    def name(self) -> str:
76        return self._name_

The name of the Enum member.

value: 'typing.Any'
78    @property
79    def value(self) -> typing.Any:
80        return self._value_

The value of the Enum member.

@typing.final
class FireteamActivity(builtins.int, aiobungie.Enum):
 65@typing.final
 66class FireteamActivity(int, enums.Enum):
 67    """An enum for the fireteam activities."""
 68
 69    ALL = 0
 70    CRUCIBLE = 2
 71    TRIALS_OF_OSIRIS = 3
 72    NIGHTFALL = 4
 73    ANY = 5
 74    GAMBIT = 6
 75    BLIND_WELL = 7
 76    NIGHTMARE_HUNTS = 12
 77    ALTARS_OF_SORROWS = 14
 78    DUNGEON = 15
 79    RAID_LW = 20
 80    RAID_GOS = 21
 81    RAID_DSC = 22
 82    EXO_CHALLENGE = 23
 83    S12_WRATHBORN = 24
 84    EMPIRE_HUNTS = 25
 85    S13_BATTLEGROUNDS = 26
 86    EXOTIC_QUEST = 27
 87    RAID_VOG = 28
 88    S14_EXPUNGE = 30
 89    S15_ASTRAL_ALIGNMENT = 31
 90    S15_SHATTERED_RELAM = 32
 91    SHATTERED_THRONE = 33
 92    PROPHECY = 34
 93    PIT_OF_HERESY = 35
 94    DUNGEON_DOE = 36
 95    """Dares of Eternity."""
 96    DUNGEON_GOA = 37
 97    """Grasp of Avarice."""
 98    VOW_OF_THE_DISCIPLE = 38
 99    CAMPAIGN = 39
100    WELLSPRING = 40
101    S16_BATTLEGROUNDS = 41
102    S17_NIGHTMARE_CONTAINMENT = 44
103    S17_SEVER = 45

An enum for the fireteam activities.

CRUCIBLE = <FireteamActivity.CRUCIBLE: 2>
TRIALS_OF_OSIRIS = <FireteamActivity.TRIALS_OF_OSIRIS: 3>
NIGHTFALL = <FireteamActivity.NIGHTFALL: 4>
GAMBIT = <FireteamActivity.GAMBIT: 6>
BLIND_WELL = <FireteamActivity.BLIND_WELL: 7>
NIGHTMARE_HUNTS = <FireteamActivity.NIGHTMARE_HUNTS: 12>
ALTARS_OF_SORROWS = <FireteamActivity.ALTARS_OF_SORROWS: 14>
DUNGEON = <FireteamActivity.DUNGEON: 15>
RAID_LW = <FireteamActivity.RAID_LW: 20>
RAID_GOS = <FireteamActivity.RAID_GOS: 21>
RAID_DSC = <FireteamActivity.RAID_DSC: 22>
EXO_CHALLENGE = <FireteamActivity.EXO_CHALLENGE: 23>
S12_WRATHBORN = <FireteamActivity.S12_WRATHBORN: 24>
EMPIRE_HUNTS = <FireteamActivity.EMPIRE_HUNTS: 25>
S13_BATTLEGROUNDS = <FireteamActivity.S13_BATTLEGROUNDS: 26>
EXOTIC_QUEST = <FireteamActivity.EXOTIC_QUEST: 27>
RAID_VOG = <FireteamActivity.RAID_VOG: 28>
S14_EXPUNGE = <FireteamActivity.S14_EXPUNGE: 30>
S15_ASTRAL_ALIGNMENT = <FireteamActivity.S15_ASTRAL_ALIGNMENT: 31>
S15_SHATTERED_RELAM = <FireteamActivity.S15_SHATTERED_RELAM: 32>
SHATTERED_THRONE = <FireteamActivity.SHATTERED_THRONE: 33>
PROPHECY = <FireteamActivity.PROPHECY: 34>
PIT_OF_HERESY = <FireteamActivity.PIT_OF_HERESY: 35>
DUNGEON_DOE = <FireteamActivity.DUNGEON_DOE: 36>

Dares of Eternity.

DUNGEON_GOA = <FireteamActivity.DUNGEON_GOA: 37>

Grasp of Avarice.

VOW_OF_THE_DISCIPLE = <FireteamActivity.VOW_OF_THE_DISCIPLE: 38>
CAMPAIGN = <FireteamActivity.CAMPAIGN: 39>
WELLSPRING = <FireteamActivity.WELLSPRING: 40>
S16_BATTLEGROUNDS = <FireteamActivity.S16_BATTLEGROUNDS: 41>
S17_NIGHTMARE_CONTAINMENT = <FireteamActivity.S17_NIGHTMARE_CONTAINMENT: 44>
S17_SEVER = <FireteamActivity.S17_SEVER: 45>
Inherited Members
Enum
name
value
@typing.final
class FireteamDate(builtins.int, aiobungie.Enum):
129@typing.final
130class FireteamDate(int, enums.Enum):
131    """An enum for fireteam date ranges."""
132
133    ALL = 0
134    NOW = 1
135    TODAY = 2
136    TWO_DAYS = 3
137    THIS_WEEK = 4

An enum for fireteam date ranges.

ALL = <FireteamDate.ALL: 0>
NOW = <FireteamDate.NOW: 1>
TODAY = <FireteamDate.TODAY: 2>
TWO_DAYS = <FireteamDate.TWO_DAYS: 3>
THIS_WEEK = <FireteamDate.THIS_WEEK: 4>
Inherited Members
Enum
name
value
@typing.final
class FireteamLanguage(builtins.str, aiobungie.Enum):
106@typing.final
107class FireteamLanguage(str, enums.Enum):
108    """An enum for fireteams languages filters."""
109
110    ALL = ""
111    ENGLISH = "en"
112    FRENCH = "fr"
113    ESPANOL = "es"
114    DEUTSCH = "de"
115    ITALIAN = "it"
116    JAPANESE = "ja"
117    PORTUGUESE = "pt-br"
118    RUSSIAN = "ru"
119    POLISH = "pl"
120    KOREAN = "ko"
121    # ? China
122    ZH_CHT = "zh-cht"
123    ZH_CHS = "zh-chs"
124
125    def __str__(self) -> str:
126        return str(self.value)

An enum for fireteams languages filters.

ENGLISH = <FireteamLanguage.ENGLISH: en>
FRENCH = <FireteamLanguage.FRENCH: fr>
ESPANOL = <FireteamLanguage.ESPANOL: es>
DEUTSCH = <FireteamLanguage.DEUTSCH: de>
ITALIAN = <FireteamLanguage.ITALIAN: it>
JAPANESE = <FireteamLanguage.JAPANESE: ja>
PORTUGUESE = <FireteamLanguage.PORTUGUESE: pt-br>
RUSSIAN = <FireteamLanguage.RUSSIAN: ru>
POLISH = <FireteamLanguage.POLISH: pl>
KOREAN = <FireteamLanguage.KOREAN: ko>
ZH_CHT = <FireteamLanguage.ZH_CHT: zh-cht>
ZH_CHS = <FireteamLanguage.ZH_CHS: zh-chs>
Inherited Members
Enum
name
value
@typing.final
class FireteamPlatform(builtins.int, aiobungie.Enum):
52@typing.final
53class FireteamPlatform(int, enums.Enum):
54    """An enum for fireteam related to bungie fireteams.
55    This is different from the normal `aiobungie.MembershipType`.
56    """
57
58    ANY = 0
59    PSN_NETWORK = 1
60    XBOX_LIVE = 2
61    STEAM = 4
62    STADIA = 5

An enum for fireteam related to bungie fireteams. This is different from the normal aiobungie.MembershipType.

PSN_NETWORK = <FireteamPlatform.PSN_NETWORK: 1>
XBOX_LIVE = <FireteamPlatform.XBOX_LIVE: 2>
STEAM = <FireteamPlatform.STEAM: 4>
STADIA = <FireteamPlatform.STADIA: 5>
Inherited Members
Enum
name
value
class Flag(enum.Flag):
 92class Flag(__enum.Flag):
 93    """Builtin Python enum flag with extra handlings."""
 94
 95    # Needs to type this here for mypy
 96    _value_: int
 97
 98    @property
 99    def name(self) -> str:
100        if self._name_ is None:
101            self._name_ = f"UNKNOWN {self._value_}"
102
103        return self._name_
104
105    @property
106    def value(self) -> int:
107        return self._value_
108
109    def __str__(self) -> str:
110        return self.name
111
112    def __repr__(self) -> str:
113        return f"<{type(self).__name__}.{self.name}: {self._value_!s}>"
114
115    def __int__(self) -> int:
116        return int(self.value)
117
118    def __or__(self, other: Flag | int) -> Flag:
119        return self.__class__(self._value_ | int(other))
120
121    def __xor__(self, other: Flag | int) -> Flag:
122        return self.__class__(self._value_ ^ int(other))
123
124    def __and__(self, other: Flag | int) -> Flag:
125        return self.__class__(other & int(other))
126
127    def __invert__(self) -> Flag:
128        return self.__class__(~self._value_)
129
130    def __contains__(self, other: Flag | int) -> bool:
131        return self.value & int(other) == int(other)

Builtin Python enum flag with extra handlings.

name: 'str'
 98    @property
 99    def name(self) -> str:
100        if self._name_ is None:
101            self._name_ = f"UNKNOWN {self._value_}"
102
103        return self._name_

The name of the Enum member.

value: 'int'
105    @property
106    def value(self) -> int:
107        return self._value_

The value of the Enum member.

@attrs.define(auto_exc=True)
class Forbidden(aiobungie.HTTPException):
144@attrs.define(auto_exc=True)
145class Forbidden(HTTPException):
146    """Exception that's raised for when status code 403 occurs."""
147
148    http_status: http.HTTPStatus = attrs.field(
149        default=http.HTTPStatus.FORBIDDEN, init=False
150    )

Exception that's raised for when status code 403 occurs.

Forbidden( *, error_code: 'int', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.throttle_seconds = throttle_seconds
20    self.url = url
21    self.body = body
22    self.headers = headers
23    self.message = message
24    self.error_status = error_status
25    self.message_data = message_data
26    self.http_status = attr_dict['http_status'].default
27    BaseException.__init__(self, self.error_code,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class Forbidden.

http_status: 'http.HTTPStatus'

The request response http status.

@typing.final
class GameMode(builtins.int, aiobungie.Enum):
260@typing.final
261class GameMode(int, Enum):
262    """An Enum for all available gamemodes in Destiny 2."""
263
264    NONE = 0
265    STORY = 2
266    STRIKE = 3
267    RAID = 4
268    ALLPVP = 5
269    PATROL = 6
270    ALLPVE = 7
271    RESERVED9 = 9
272    CONTROL = 10
273    RESERVED11 = 11
274    CLASH = 12
275    RESERVED13 = 13
276    CRIMSONDOUBLES = 15
277    NIGHTFALL = 16
278    HEROICNIGHTFALL = 17
279    ALLSTRIKES = 18
280    IRONBANNER = 19
281    RESERVED20 = 20
282    RESERVED21 = 21
283    RESERVED22 = 22
284    RESERVED24 = 24
285    ALLMAYHEM = 25
286    RESERVED26 = 26
287    RESERVED27 = 27
288    RESERVED28 = 28
289    RESERVED29 = 29
290    RESERVED30 = 30
291    SUPREMACY = 31
292    PRIVATEMATCHESALL = 32
293    SURVIVAL = 37
294    COUNTDOWN = 38
295    TRIALSOFTHENINE = 39
296    SOCIAL = 40
297    TRIALSCOUNTDOWN = 41
298    TRIALSSURVIVAL = 42
299    IRONBANNERCONTROL = 43
300    IRONBANNERCLASH = 44
301    IRONBANNERSUPREMACY = 45
302    SCOREDNIGHTFALL = 46
303    SCOREDHEROICNIGHTFALL = 47
304    RUMBLE = 48
305    ALLDOUBLES = 49
306    DOUBLES = 50
307    PRIVATEMATCHESCLASH = 51
308    PRIVATEMATCHESCONTROL = 52
309    PRIVATEMATCHESSUPREMACY = 53
310    PRIVATEMATCHESCOUNTDOWN = 54
311    PRIVATEMATCHESSURVIVAL = 55
312    PRIVATEMATCHESMAYHEM = 56
313    PRIVATEMATCHESRUMBLE = 57
314    HEROICADVENTURE = 58
315    SHOWDOWN = 59
316    LOCKDOWN = 60
317    SCORCHED = 61
318    SCORCHEDTEAM = 62
319    GAMBIT = 63
320    ALLPVECOMPETITIVE = 64
321    BREAKTHROUGH = 65
322    BLACKARMORYRUN = 66
323    SALVAGE = 67
324    IRONBANNERSALVAGE = 68
325    PVPCOMPETITIVE = 69
326    PVPQUICKPLAY = 70
327    CLASHQUICKPLAY = 71
328    CLASHCOMPETITIVE = 72
329    CONTROLQUICKPLAY = 73
330    CONTROLCOMPETITIVE = 74
331    GAMBITPRIME = 75
332    RECKONING = 76
333    MENAGERIE = 77
334    VEXOFFENSIVE = 78
335    NIGHTMAREHUNT = 79
336    ELIMINATION = 80
337    MOMENTUM = 81
338    DUNGEON = 82
339    SUNDIAL = 83
340    TRIALS_OF_OSIRIS = 84
341    DARES = 85
342    OFFENSIVE = 86
343    LOSTSECTOR = 87
344    RIFT = 88
345    ZONECONTROL = 89
346    IRONBANNERRIFT = 90

An Enum for all available gamemodes in Destiny 2.

NONE = <GameMode.NONE: 0>
STORY = <GameMode.STORY: 2>
STRIKE = <GameMode.STRIKE: 3>
RAID = <GameMode.RAID: 4>
ALLPVP = <GameMode.ALLPVP: 5>
PATROL = <GameMode.PATROL: 6>
ALLPVE = <GameMode.ALLPVE: 7>
RESERVED9 = <GameMode.RESERVED9: 9>
CONTROL = <GameMode.CONTROL: 10>
RESERVED11 = <GameMode.RESERVED11: 11>
CLASH = <GameMode.CLASH: 12>
RESERVED13 = <GameMode.RESERVED13: 13>
CRIMSONDOUBLES = <GameMode.CRIMSONDOUBLES: 15>
NIGHTFALL = <GameMode.NIGHTFALL: 16>
HEROICNIGHTFALL = <GameMode.HEROICNIGHTFALL: 17>
ALLSTRIKES = <GameMode.ALLSTRIKES: 18>
IRONBANNER = <GameMode.IRONBANNER: 19>
RESERVED20 = <GameMode.RESERVED20: 20>
RESERVED21 = <GameMode.RESERVED21: 21>
RESERVED22 = <GameMode.RESERVED22: 22>
RESERVED24 = <GameMode.RESERVED24: 24>
ALLMAYHEM = <GameMode.ALLMAYHEM: 25>
RESERVED26 = <GameMode.RESERVED26: 26>
RESERVED27 = <GameMode.RESERVED27: 27>
RESERVED28 = <GameMode.RESERVED28: 28>
RESERVED29 = <GameMode.RESERVED29: 29>
RESERVED30 = <GameMode.RESERVED30: 30>
SUPREMACY = <GameMode.SUPREMACY: 31>
PRIVATEMATCHESALL = <GameMode.PRIVATEMATCHESALL: 32>
SURVIVAL = <GameMode.SURVIVAL: 37>
COUNTDOWN = <GameMode.COUNTDOWN: 38>
TRIALSOFTHENINE = <GameMode.TRIALSOFTHENINE: 39>
SOCIAL = <GameMode.SOCIAL: 40>
TRIALSCOUNTDOWN = <GameMode.TRIALSCOUNTDOWN: 41>
TRIALSSURVIVAL = <GameMode.TRIALSSURVIVAL: 42>
IRONBANNERCONTROL = <GameMode.IRONBANNERCONTROL: 43>
IRONBANNERCLASH = <GameMode.IRONBANNERCLASH: 44>
IRONBANNERSUPREMACY = <GameMode.IRONBANNERSUPREMACY: 45>
SCOREDNIGHTFALL = <GameMode.SCOREDNIGHTFALL: 46>
SCOREDHEROICNIGHTFALL = <GameMode.SCOREDHEROICNIGHTFALL: 47>
RUMBLE = <GameMode.RUMBLE: 48>
ALLDOUBLES = <GameMode.ALLDOUBLES: 49>
DOUBLES = <GameMode.DOUBLES: 50>
PRIVATEMATCHESCLASH = <GameMode.PRIVATEMATCHESCLASH: 51>
PRIVATEMATCHESCONTROL = <GameMode.PRIVATEMATCHESCONTROL: 52>
PRIVATEMATCHESSUPREMACY = <GameMode.PRIVATEMATCHESSUPREMACY: 53>
PRIVATEMATCHESCOUNTDOWN = <GameMode.PRIVATEMATCHESCOUNTDOWN: 54>
PRIVATEMATCHESSURVIVAL = <GameMode.PRIVATEMATCHESSURVIVAL: 55>
PRIVATEMATCHESMAYHEM = <GameMode.PRIVATEMATCHESMAYHEM: 56>
PRIVATEMATCHESRUMBLE = <GameMode.PRIVATEMATCHESRUMBLE: 57>
HEROICADVENTURE = <GameMode.HEROICADVENTURE: 58>
SHOWDOWN = <GameMode.SHOWDOWN: 59>
LOCKDOWN = <GameMode.LOCKDOWN: 60>
SCORCHED = <GameMode.SCORCHED: 61>
SCORCHEDTEAM = <GameMode.SCORCHEDTEAM: 62>
GAMBIT = <GameMode.GAMBIT: 63>
ALLPVECOMPETITIVE = <GameMode.ALLPVECOMPETITIVE: 64>
BREAKTHROUGH = <GameMode.BREAKTHROUGH: 65>
BLACKARMORYRUN = <GameMode.BLACKARMORYRUN: 66>
SALVAGE = <GameMode.SALVAGE: 67>
IRONBANNERSALVAGE = <GameMode.IRONBANNERSALVAGE: 68>
PVPCOMPETITIVE = <GameMode.PVPCOMPETITIVE: 69>
PVPQUICKPLAY = <GameMode.PVPQUICKPLAY: 70>
CLASHQUICKPLAY = <GameMode.CLASHQUICKPLAY: 71>
CLASHCOMPETITIVE = <GameMode.CLASHCOMPETITIVE: 72>
CONTROLQUICKPLAY = <GameMode.CONTROLQUICKPLAY: 73>
CONTROLCOMPETITIVE = <GameMode.CONTROLCOMPETITIVE: 74>
GAMBITPRIME = <GameMode.GAMBITPRIME: 75>
RECKONING = <GameMode.RECKONING: 76>
MENAGERIE = <GameMode.MENAGERIE: 77>
VEXOFFENSIVE = <GameMode.VEXOFFENSIVE: 78>
NIGHTMAREHUNT = <GameMode.NIGHTMAREHUNT: 79>
ELIMINATION = <GameMode.ELIMINATION: 80>
MOMENTUM = <GameMode.MOMENTUM: 81>
DUNGEON = <GameMode.DUNGEON: 82>
SUNDIAL = <GameMode.SUNDIAL: 83>
TRIALS_OF_OSIRIS = <GameMode.TRIALS_OF_OSIRIS: 84>
DARES = <GameMode.DARES: 85>
OFFENSIVE = <GameMode.OFFENSIVE: 86>
LOSTSECTOR = <GameMode.LOSTSECTOR: 87>
RIFT = <GameMode.RIFT: 88>
ZONECONTROL = <GameMode.ZONECONTROL: 89>
IRONBANNERRIFT = <GameMode.IRONBANNERRIFT: 90>
Inherited Members
Enum
name
value
@typing.final
class GameVersions(aiobungie.Flag):
824@typing.final
825class GameVersions(Flag):
826    """An enum that holds all available Destiny 2 game versions. aka DLCs"""
827
828    NONE = 0 << 0  # always 0
829    DESTINY_2 = 1 << 0
830    DLC1 = 1 << 1
831    DLC2 = 1 << 2
832    FORSAKEN = 1 << 3
833    YEAR_TWO_ANNUAL_PASS = 1 << 4
834    SHADOW_KEEP = 1 << 5
835    BEYOND_LIGHT = 1 << 6
836    ANNIVERSARY_30TH = 1 << 7
837    THE_WITCH_QUEEN = 1 << 8
838    LIGHT_FALL = 1 << 9
839    THE_FINAL_SHAPE = 1 << 10

An enum that holds all available Destiny 2 game versions. aka DLCs

NONE = <GameVersions.NONE: 0>
DESTINY_2 = <GameVersions.DESTINY_2: 1>
DLC1 = <GameVersions.DLC1: 2>
DLC2 = <GameVersions.DLC2: 4>
FORSAKEN = <GameVersions.FORSAKEN: 8>
YEAR_TWO_ANNUAL_PASS = <GameVersions.YEAR_TWO_ANNUAL_PASS: 16>
SHADOW_KEEP = <GameVersions.SHADOW_KEEP: 32>
BEYOND_LIGHT = <GameVersions.BEYOND_LIGHT: 64>
ANNIVERSARY_30TH = <GameVersions.ANNIVERSARY_30TH: 128>
THE_WITCH_QUEEN = <GameVersions.THE_WITCH_QUEEN: 256>
LIGHT_FALL = <GameVersions.LIGHT_FALL: 512>
THE_FINAL_SHAPE = <GameVersions.THE_FINAL_SHAPE: 1024>
Inherited Members
Flag
name
value
@typing.final
class GatingScope(builtins.int, aiobungie.Enum):
55@typing.final
56class GatingScope(int, enums.Enum):
57    """An enum represents restrictive type of gating that is being performed by an entity.
58
59    This is useful as a shortcut to avoid a lot of lookups when determining whether the gating on an Entity
60    applies to everyone equally, or to their specific Profile or Character states.
61    """
62
63    NONE = 0
64    GLOBAL = 1
65    CLAN = 2
66    PROFILE = 3
67    CHARACTER = 4
68    ITEM = 5
69    ASSUMED_WORST_CASE = 6

An enum represents restrictive type of gating that is being performed by an entity.

This is useful as a shortcut to avoid a lot of lookups when determining whether the gating on an Entity applies to everyone equally, or to their specific Profile or Character states.

NONE = <GatingScope.NONE: 0>
GLOBAL = <GatingScope.GLOBAL: 1>
CLAN = <GatingScope.CLAN: 2>
PROFILE = <GatingScope.PROFILE: 3>
CHARACTER = <GatingScope.CHARACTER: 4>
ITEM = <GatingScope.ITEM: 5>
ASSUMED_WORST_CASE = <GatingScope.ASSUMED_WORST_CASE: 6>
Inherited Members
Enum
name
value
@typing.final
class Gender(builtins.int, aiobungie.Enum):
479@typing.final
480class Gender(int, Enum):
481    """An Enum for Destiny Genders."""
482
483    MALE = 0
484    FEMALE = 1
485    UNKNOWN = 2

An Enum for Destiny Genders.

MALE = <Gender.MALE: 0>
FEMALE = <Gender.FEMALE: 1>
UNKNOWN = <Gender.UNKNOWN: 2>
Inherited Members
Enum
name
value
@typing.final
class GroupDate(builtins.int, aiobungie.Enum):
56@typing.final
57class GroupDate(int, enums.Enum):
58    ALL = 0
59    PAST_DAY = 1
60    PAST_WEEK = 2
61    PAST_MONTH = 3
62    PAST_YEAR = 4

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

>>> int('0b100', base=0)
4
ALL = <GroupDate.ALL: 0>
PAST_DAY = <GroupDate.PAST_DAY: 1>
PAST_WEEK = <GroupDate.PAST_WEEK: 2>
PAST_MONTH = <GroupDate.PAST_MONTH: 3>
PAST_YEAR = <GroupDate.PAST_YEAR: 4>
Inherited Members
Enum
name
value
@typing.final
class GroupType(builtins.int, aiobungie.Enum):
648@typing.final
649class GroupType(int, Enum):
650    """An enums for the known bungie group types."""
651
652    GENERAL = 0
653    CLAN = 1

An enums for the known bungie group types.

GENERAL = <GroupType.GENERAL: 0>
CLAN = <GroupType.CLAN: 1>
Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class HTTPError(aiobungie.AiobungieError):
83@attrs.define(auto_exc=True)
84class HTTPError(AiobungieError):
85    """Base HTTP request errors exception."""
86
87    message: str
88    """The error message."""
89
90    http_status: http.HTTPStatus
91    """The response status."""

Base HTTP request errors exception.

HTTPError(message: 'str', http_status: 'http.HTTPStatus')
17def __init__(self, message, http_status):
18    self.message = message
19    self.http_status = http_status
20    BaseException.__init__(self, self.message,self.http_status)

Method generated by attrs for class HTTPError.

message: 'str'

The error message.

http_status: 'http.HTTPStatus'

The response status.

@attrs.define(auto_exc=True, kw_only=True)
class HTTPException(aiobungie.HTTPError):
 94@attrs.define(auto_exc=True, kw_only=True)
 95class HTTPException(HTTPError):
 96    """An in-depth HTTP exception that's raised with more information."""
 97
 98    error_code: int
 99    """The returned Bungie error status code."""
100
101    http_status: http.HTTPStatus
102    """The request response http status."""
103
104    throttle_seconds: int
105    """The Bungie response throttle seconds."""
106
107    url: typedefs.StrOrURL | None
108    """The URL/endpoint caused this error."""
109
110    body: typing.Any
111    """The response body."""
112
113    headers: multidict.CIMultiDictProxy[str]
114    """The response headers."""
115
116    message: str
117    """A Bungie human readable message describes the cause of the error."""
118
119    error_status: str
120    """A Bungie short error status describes the cause of the error."""
121
122    message_data: dict[str, str]
123    """A dict of string key, value that includes each cause of the error
124    to a message describes information about that error.
125    """
126
127    def __str__(self) -> str:
128        status_name, status_value = (
129            self.http_status.name.replace("_", "").title(),
130            self.http_status.value,
131        )
132        return (
133            f"{status_name}: " + "("
134            f"""
135            http_status: {status_value},
136            message: {self.message if self.message else "UNDEFINED"},
137            error_status: {self.error_status if self.error_status else "UNDEFINED"},
138            url: {self.url if self.url else "UNDEFINED"},
139            message_data: {self.message_data}
140        """ + ")"
141        )

An in-depth HTTP exception that's raised with more information.

HTTPException( *, error_code: 'int', http_status: 'http.HTTPStatus', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, http_status, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.http_status = http_status
20    self.throttle_seconds = throttle_seconds
21    self.url = url
22    self.body = body
23    self.headers = headers
24    self.message = message
25    self.error_status = error_status
26    self.message_data = message_data
27    BaseException.__init__(self, self.error_code,self.http_status,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class HTTPException.

error_code: 'int'

The returned Bungie error status code.

http_status: 'http.HTTPStatus'

The request response http status.

throttle_seconds: 'int'

The Bungie response throttle seconds.

url: 'typedefs.StrOrURL | None'

The URL/endpoint caused this error.

body: 'typing.Any'

The response body.

headers: 'multidict.CIMultiDictProxy[str]'

The response headers.

message: 'str'

A Bungie human readable message describes the cause of the error.

error_status: 'str'

A Bungie short error status describes the cause of the error.

message_data: 'dict[str, str]'

A dict of string key, value that includes each cause of the error to a message describes information about that error.

@attrs.define(auto_exc=True)
class InternalServerError(aiobungie.HTTPException):
248@attrs.define(auto_exc=True)
249class InternalServerError(HTTPException):
250    """Raised for 5xx internal server errors."""

Raised for 5xx internal server errors.

InternalServerError( *, error_code: 'int', http_status: 'http.HTTPStatus', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, http_status, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.http_status = http_status
20    self.throttle_seconds = throttle_seconds
21    self.url = url
22    self.body = body
23    self.headers = headers
24    self.message = message
25    self.error_status = error_status
26    self.message_data = message_data
27    BaseException.__init__(self, self.error_code,self.http_status,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class InternalServerError.

@typing.final
class ItemBindStatus(builtins.int, aiobungie.Enum):
714@typing.final
715class ItemBindStatus(int, Enum):
716    """An enum for Destiny 2 items bind status."""
717
718    NOT_BOUND = 0
719    BOUND_TO_CHARACTER = 1
720    BOUND_TO_ACCOUNT = 2
721    BOUNT_TO_GUILD = 3

An enum for Destiny 2 items bind status.

NOT_BOUND = <ItemBindStatus.NOT_BOUND: 0>
BOUND_TO_CHARACTER = <ItemBindStatus.BOUND_TO_CHARACTER: 1>
BOUND_TO_ACCOUNT = <ItemBindStatus.BOUND_TO_ACCOUNT: 2>
BOUNT_TO_GUILD = <ItemBindStatus.BOUNT_TO_GUILD: 3>
Inherited Members
Enum
name
value
@typing.final
class ItemLocation(builtins.int, aiobungie.Enum):
724@typing.final
725class ItemLocation(int, Enum):
726    """An enum for Destiny 2 items location."""
727
728    UNKNOWN = 0
729    INVENTORY = 1
730    VAULT = 2
731    VENDOR = 3
732    POSTMASTER = 4

An enum for Destiny 2 items location.

UNKNOWN = <ItemLocation.UNKNOWN: 0>
INVENTORY = <ItemLocation.INVENTORY: 1>
VAULT = <ItemLocation.VAULT: 2>
VENDOR = <ItemLocation.VENDOR: 3>
POSTMASTER = <ItemLocation.POSTMASTER: 4>
Inherited Members
Enum
name
value
@typing.final
class ItemState(aiobungie.Flag):
749@typing.final
750class ItemState(Flag):
751    """An enum for Destiny 2 item states."""
752
753    NONE = 0
754    LOCKED = 1 << 0
755    TRACKED = 1 << 1
756    MASTERWORKED = 1 << 2
757    CRAFTED = 1 << 3
758    """If this bit is set, the item has been 'crafted' by the player."""
759    HIGHLITED_OBJECTIVE = 1 << 4
760    """If this bit is set, the item is a 'highlighted' objective."""

An enum for Destiny 2 item states.

NONE = <ItemState.NONE: 0>
LOCKED = <ItemState.LOCKED: 1>
TRACKED = <ItemState.TRACKED: 2>
MASTERWORKED = <ItemState.MASTERWORKED: 4>
CRAFTED = <ItemState.CRAFTED: 8>

If this bit is set, the item has been 'crafted' by the player.

HIGHLITED_OBJECTIVE = <ItemState.HIGHLITED_OBJECTIVE: 16>

If this bit is set, the item is a 'highlighted' objective.

Inherited Members
Flag
name
value
@typing.final
class ItemSubType(builtins.int, aiobungie.Enum):
581@typing.final
582class ItemSubType(int, Enum):
583    """An enum for Destiny 2 inventory items subtype."""
584
585    NONE = 0
586    AUTORIFLE = 6
587    SHOTGUN = 7
588    MACHINEGUN = 8
589    HANDCANNON = 9
590    ROCKETLAUNCHER = 10
591    FUSIONRIFLE = 11
592    SNIPERRIFLE = 12
593    PULSERIFLE = 13
594    SCOUTRIFLE = 14
595    SIDEARM = 17
596    SWORD = 18
597    MASK = 19
598    SHADER = 20
599    ORNAMENT = 21
600    FUSIONRIFLELINE = 22
601    GRENADELAUNCHER = 23
602    SUBMACHINEGUN = 24
603    TRACERIFLE = 25
604    HELMETARMOR = 26
605    GAUNTLETSARMOR = 27
606    CHESTARMOR = 28
607    LEGARMOR = 29
608    CLASSARMOR = 30
609    BOW = 31
610    DUMMYREPEATABLEBOUNTY = 32

An enum for Destiny 2 inventory items subtype.

NONE = <ItemSubType.NONE: 0>
AUTORIFLE = <ItemSubType.AUTORIFLE: 6>
SHOTGUN = <ItemSubType.SHOTGUN: 7>
MACHINEGUN = <ItemSubType.MACHINEGUN: 8>
HANDCANNON = <ItemSubType.HANDCANNON: 9>
ROCKETLAUNCHER = <ItemSubType.ROCKETLAUNCHER: 10>
FUSIONRIFLE = <ItemSubType.FUSIONRIFLE: 11>
SNIPERRIFLE = <ItemSubType.SNIPERRIFLE: 12>
PULSERIFLE = <ItemSubType.PULSERIFLE: 13>
SCOUTRIFLE = <ItemSubType.SCOUTRIFLE: 14>
SIDEARM = <ItemSubType.SIDEARM: 17>
SWORD = <ItemSubType.SWORD: 18>
MASK = <ItemSubType.MASK: 19>
SHADER = <ItemSubType.SHADER: 20>
ORNAMENT = <ItemSubType.ORNAMENT: 21>
FUSIONRIFLELINE = <ItemSubType.FUSIONRIFLELINE: 22>
GRENADELAUNCHER = <ItemSubType.GRENADELAUNCHER: 23>
SUBMACHINEGUN = <ItemSubType.SUBMACHINEGUN: 24>
TRACERIFLE = <ItemSubType.TRACERIFLE: 25>
HELMETARMOR = <ItemSubType.HELMETARMOR: 26>
GAUNTLETSARMOR = <ItemSubType.GAUNTLETSARMOR: 27>
CHESTARMOR = <ItemSubType.CHESTARMOR: 28>
LEGARMOR = <ItemSubType.LEGARMOR: 29>
CLASSARMOR = <ItemSubType.CLASSARMOR: 30>
BOW = <ItemSubType.BOW: 31>
DUMMYREPEATABLEBOUNTY = <ItemSubType.DUMMYREPEATABLEBOUNTY: 32>
Inherited Members
Enum
name
value
@typing.final
class ItemTier(builtins.int, aiobungie.Enum):
613@typing.final
614class ItemTier(int, Enum):
615    """An enum for a Destiny 2 item tier."""
616
617    NONE = 0
618    BASIC = 3340296461
619    COMMON = 2395677314
620    RARE = 2127292149
621    LEGENDERY = 4008398120
622    EXOTIC = 2759499571

An enum for a Destiny 2 item tier.

NONE = <ItemTier.NONE: 0>
BASIC = <ItemTier.BASIC: 3340296461>
COMMON = <ItemTier.COMMON: 2395677314>
RARE = <ItemTier.RARE: 2127292149>
LEGENDERY = <ItemTier.LEGENDERY: 4008398120>
EXOTIC = <ItemTier.EXOTIC: 2759499571>
Inherited Members
Enum
name
value
@typing.final
class ItemType(builtins.int, aiobungie.Enum):
548@typing.final
549class ItemType(int, Enum):
550    """Enums for Destiny2's item types."""
551
552    NONE = 0
553    CURRENCY = 1
554    ARMOR = 2
555    WEAPON = 3
556    MESSAGE = 7
557    ENGRAM = 8
558    CONSUMABLE = 9
559    EXCHANGEMATERIAL = 10
560    MISSIONREWARD = 11
561    QUESTSTEP = 12
562    QUESTSTEPCOMPLETE = 13
563    EMBLEM = 14
564    QUEST = 15
565    SUBCLASS = 16
566    CLANBANNER = 17
567    AURA = 18
568    MOD = 19
569    DUMMY = 20
570    SHIP = 21
571    VEHICLE = 22
572    EMOTE = 23
573    GHOST = 24
574    PACKAGE = 25
575    BOUNTY = 26
576    WRAPPER = 27
577    SEASONALARTIFACT = 28
578    FINISHER = 29

Enums for Destiny2's item types.

NONE = <ItemType.NONE: 0>
CURRENCY = <ItemType.CURRENCY: 1>
ARMOR = <ItemType.ARMOR: 2>
WEAPON = <ItemType.WEAPON: 3>
MESSAGE = <ItemType.MESSAGE: 7>
ENGRAM = <ItemType.ENGRAM: 8>
CONSUMABLE = <ItemType.CONSUMABLE: 9>
EXCHANGEMATERIAL = <ItemType.EXCHANGEMATERIAL: 10>
MISSIONREWARD = <ItemType.MISSIONREWARD: 11>
QUESTSTEP = <ItemType.QUESTSTEP: 12>
QUESTSTEPCOMPLETE = <ItemType.QUESTSTEPCOMPLETE: 13>
EMBLEM = <ItemType.EMBLEM: 14>
QUEST = <ItemType.QUEST: 15>
SUBCLASS = <ItemType.SUBCLASS: 16>
CLANBANNER = <ItemType.CLANBANNER: 17>
AURA = <ItemType.AURA: 18>
MOD = <ItemType.MOD: 19>
DUMMY = <ItemType.DUMMY: 20>
SHIP = <ItemType.SHIP: 21>
VEHICLE = <ItemType.VEHICLE: 22>
EMOTE = <ItemType.EMOTE: 23>
GHOST = <ItemType.GHOST: 24>
PACKAGE = <ItemType.PACKAGE: 25>
BOUNTY = <ItemType.BOUNTY: 26>
WRAPPER = <ItemType.WRAPPER: 27>
SEASONALARTIFACT = <ItemType.SEASONALARTIFACT: 28>
FINISHER = <ItemType.FINISHER: 29>
Inherited Members
Enum
name
value
@typing.final
class MembershipOption(builtins.int, aiobungie.Enum):
705@typing.final
706class MembershipOption(int, Enum):
707    """A enum for GroupV2 membership options."""
708
709    REVIEWD = 0
710    OPEN = 1
711    CLOSED = 2

A enum for GroupV2 membership options.

REVIEWD = <MembershipOption.REVIEWD: 0>
OPEN = <MembershipOption.OPEN: 1>
CLOSED = <MembershipOption.CLOSED: 2>
Inherited Members
Enum
name
value
@typing.final
class MembershipType(builtins.int, aiobungie.Enum):
453@typing.final
454class MembershipType(int, Enum):
455    """An Enum for Bungie membership types."""
456
457    NONE = 0
458    XBOX = 1
459    PSN = 2
460    STEAM = 3
461    BLIZZARD = 4
462    STADIA = 5
463    EPIC_GAMES_STORE = 6
464    DEMON = 10
465    BUNGIE = 254
466    ALL = -1

An Enum for Bungie membership types.

NONE = <MembershipType.NONE: 0>
XBOX = <MembershipType.XBOX: 1>
PSN = <MembershipType.PSN: 2>
STEAM = <MembershipType.STEAM: 3>
BLIZZARD = <MembershipType.BLIZZARD: 4>
STADIA = <MembershipType.STADIA: 5>
EPIC_GAMES_STORE = <MembershipType.EPIC_GAMES_STORE: 6>
DEMON = <MembershipType.DEMON: 10>
BUNGIE = <MembershipType.BUNGIE: 254>
ALL = <MembershipType.ALL: -1>
Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class MembershipTypeError(aiobungie.BadRequest):
189@attrs.define(auto_exc=True)
190class MembershipTypeError(BadRequest):
191    """A bad request error raised when passing wrong membership to the request.
192
193    Those fields are useful since it returns the correct membership and id which can be used
194    to make the request again with those fields.
195
196    Example
197    -------
198    ```py
199    try:
200        profile = await client.fetch_profile(
201            member_id=1,
202            type=aiobungie.MembershipType.STADIA,
203            components=()
204        )
205
206    # Membership type is wrong!
207    except aiobungie.MembershipTypeError as err:
208        correct_membership = err.into_membership()
209        profile_id = err.membership_id
210
211        # Recall the method.
212        profile = await client.fetch_profile(
213            member_id=profile_id,
214            type=correct_membership,
215            components=()
216        )
217    ```
218    """
219
220    membership_type: str
221    """The errored membership type passed to the request."""
222
223    membership_id: int
224    """The errored user's membership id."""
225
226    required_membership: str
227    """The required correct membership for errored user."""
228
229    def into_membership(self, value: str | None = None) -> enums.MembershipType:
230        """Turn the required membership from `str` into `aiobungie.Membership` type.
231
232        If value parameter is not provided it will fall back to the required membership.
233        """
234        if value is None:
235            return _MEMBERSHIP_LOOKUP[self.required_membership]
236        return _MEMBERSHIP_LOOKUP[value]
237
238    def __str__(self) -> str:
239        return (
240            f"Expected membership: {self.into_membership().name.replace('_', '').title()}, "
241            f"But got {self.into_membership(self.membership_type)} for id {self.membership_id}"
242        )
243
244    def __int__(self) -> int:
245        return int(self.membership_id)

A bad request error raised when passing wrong membership to the request.

Those fields are useful since it returns the correct membership and id which can be used to make the request again with those fields.

Example
try:
    profile = await client.fetch_profile(
        member_id=1,
        type=aiobungie.MembershipType.STADIA,
        components=()
    )

# Membership type is wrong!
except aiobungie.MembershipTypeError as err:
    correct_membership = err.into_membership()
    profile_id = err.membership_id

    # Recall the method.
    profile = await client.fetch_profile(
        member_id=profile_id,
        type=correct_membership,
        components=()
    )
MembershipTypeError( message: 'str', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', membership_type: 'str', membership_id: 'int', required_membership: 'str')
17def __init__(self, message, url, body, headers, membership_type, membership_id, required_membership):
18    self.message = message
19    self.url = url
20    self.body = body
21    self.headers = headers
22    self.http_status = attr_dict['http_status'].default
23    self.membership_type = membership_type
24    self.membership_id = membership_id
25    self.required_membership = required_membership
26    BaseException.__init__(self, self.message,self.url,self.body,self.headers,self.membership_type,self.membership_id,self.required_membership)

Method generated by attrs for class MembershipTypeError.

membership_type: 'str'

The errored membership type passed to the request.

membership_id: 'int'

The errored user's membership id.

required_membership: 'str'

The required correct membership for errored user.

def into_membership(self, value: 'str | None' = None) -> 'enums.MembershipType':
229    def into_membership(self, value: str | None = None) -> enums.MembershipType:
230        """Turn the required membership from `str` into `aiobungie.Membership` type.
231
232        If value parameter is not provided it will fall back to the required membership.
233        """
234        if value is None:
235            return _MEMBERSHIP_LOOKUP[self.required_membership]
236        return _MEMBERSHIP_LOOKUP[value]

Turn the required membership from str into aiobungie.Membership type.

If value parameter is not provided it will fall back to the required membership.

@typing.final
class MilestoneType(builtins.int, aiobungie.Enum):
498@typing.final
499class MilestoneType(int, Enum):
500    """An Enum for Destiny 2 milestone types."""
501
502    UNKNOWN = 0
503    TUTORIAL = 1
504    ONETIME = 2
505    WEEKLY = 3
506    DAILY = 4
507    SPECIAL = 5

An Enum for Destiny 2 milestone types.

UNKNOWN = <MilestoneType.UNKNOWN: 0>
TUTORIAL = <MilestoneType.TUTORIAL: 1>
ONETIME = <MilestoneType.ONETIME: 2>
WEEKLY = <MilestoneType.WEEKLY: 3>
DAILY = <MilestoneType.DAILY: 4>
SPECIAL = <MilestoneType.SPECIAL: 5>
Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class NotFound(aiobungie.HTTPException):
153@attrs.define(auto_exc=True)
154class NotFound(HTTPException):
155    """Raised when an unknown resource was not found."""
156
157    http_status: http.HTTPStatus = attrs.field(
158        default=http.HTTPStatus.NOT_FOUND, init=False
159    )

Raised when an unknown resource was not found.

NotFound( *, error_code: 'int', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.throttle_seconds = throttle_seconds
20    self.url = url
21    self.body = body
22    self.headers = headers
23    self.message = message
24    self.error_status = error_status
25    self.message_data = message_data
26    self.http_status = attr_dict['http_status'].default
27    BaseException.__init__(self, self.error_code,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class NotFound.

http_status: 'http.HTTPStatus'

The request response http status.

@typing.final
class OAuthApplicationType(builtins.int, aiobungie.Enum):
842@typing.final
843class OAuthApplicationType(int, Enum):
844    NONE = 0
845    CONFIDENTIAL = 1
846    """Indicates the application is server based and can keep its secrets from end users and other potential snoops."""
847    PUBLIC = 2
848    """Indicates the application runs in a public place, and it can't be trusted to keep a secret."""

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

>>> int('0b100', base=0)
4
CONFIDENTIAL = <OAuthApplicationType.CONFIDENTIAL: 1>

Indicates the application is server based and can keep its secrets from end users and other potential snoops.

Indicates the application runs in a public place, and it can't be trusted to keep a secret.

Inherited Members
Enum
name
value
@typing.final
class ObjectiveUIStyle(builtins.int, aiobungie.Enum):
91@typing.final
92class ObjectiveUIStyle(int, enums.Enum):
93    NONE = 0
94    HIGHLIGHTED = 1
95    CRAFTING_WEAPON_LEVEL = 2
96    CRAFTING_WEAPON_LEVEL_PROGRESS = 3
97    CRAFTING_WEAPON_TIMESTAMP = 4
98    CRAFTING_MEMENTOS = 5
99    CRAFTING_MEMENTO_TITLE = 6

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

>>> int('0b100', base=0)
4
NONE = <ObjectiveUIStyle.NONE: 0>
HIGHLIGHTED = <ObjectiveUIStyle.HIGHLIGHTED: 1>
CRAFTING_WEAPON_LEVEL = <ObjectiveUIStyle.CRAFTING_WEAPON_LEVEL: 2>
CRAFTING_WEAPON_LEVEL_PROGRESS = <ObjectiveUIStyle.CRAFTING_WEAPON_LEVEL_PROGRESS: 3>
CRAFTING_WEAPON_TIMESTAMP = <ObjectiveUIStyle.CRAFTING_WEAPON_TIMESTAMP: 4>
CRAFTING_MEMENTOS = <ObjectiveUIStyle.CRAFTING_MEMENTOS: 5>
CRAFTING_MEMENTO_TITLE = <ObjectiveUIStyle.CRAFTING_MEMENTO_TITLE: 6>
Inherited Members
Enum
name
value
@typing.final
class Place(builtins.int, aiobungie.Enum):
221@typing.final
222class Place(int, Enum):
223    """An Enum for Destiny 2 Places and NOT Planets"""
224
225    ORBIT = 2961497387
226    SOCIAL = 4151112093
227    LIGHT_HOUSE = 4276116472
228    EXPLORE = 3497767639

An Enum for Destiny 2 Places and NOT Planets

ORBIT = <Place.ORBIT: 2961497387>
SOCIAL = <Place.SOCIAL: 4151112093>
LIGHT_HOUSE = <Place.LIGHT_HOUSE: 4276116472>
EXPLORE = <Place.EXPLORE: 3497767639>
Inherited Members
Enum
name
value
@typing.final
class Planet(builtins.int, aiobungie.Enum):
186@typing.final
187class Planet(int, Enum):
188    """An Enum for all available planets in Destiny 2."""
189
190    UNKNOWN = 0
191    """Unknown space"""
192
193    EARTH = 3747705955
194    """Earth"""
195
196    DREAMING_CITY = 2877881518
197    """The Dreaming city."""
198
199    NESSUS = 3526908984
200    """Nessus"""
201
202    MOON = 3325508439
203    """The Moon"""
204
205    COSMODROME = 3990611421
206    """The Cosmodrome"""
207
208    TANGLED_SHORE = 3821439926
209    """The Tangled Shore"""
210
211    VENUS = 3871070152
212    """Venus"""
213
214    EAZ = 541863059  # Exclusive event.
215    """European Aerial Zone"""
216
217    EUROPA = 1729879943
218    """Europa"""

An Enum for all available planets in Destiny 2.

UNKNOWN = <Planet.UNKNOWN: 0>

Unknown space

EARTH = <Planet.EARTH: 3747705955>

Earth

DREAMING_CITY = <Planet.DREAMING_CITY: 2877881518>

The Dreaming city.

NESSUS = <Planet.NESSUS: 3526908984>

Nessus

MOON = <Planet.MOON: 3325508439>

The Moon

COSMODROME = <Planet.COSMODROME: 3990611421>

The Cosmodrome

TANGLED_SHORE = <Planet.TANGLED_SHORE: 3821439926>

The Tangled Shore

VENUS = <Planet.VENUS: 3871070152>

Venus

EAZ = <Planet.EAZ: 541863059>

European Aerial Zone

EUROPA = <Planet.EUROPA: 1729879943>

Europa

Inherited Members
Enum
name
value
@typing.final
class Presence(builtins.int, aiobungie.Enum):
675@typing.final
676class Presence(int, Enum):
677    """An enum for a bungie friend status."""
678
679    OFFLINE_OR_UNKNOWN = 0
680    ONLINE = 1

An enum for a bungie friend status.

OFFLINE_OR_UNKNOWN = <Presence.OFFLINE_OR_UNKNOWN: 0>
ONLINE = <Presence.ONLINE: 1>
Inherited Members
Enum
name
value
@typing.final
class PrivacySetting(builtins.int, aiobungie.Enum):
763@typing.final
764class PrivacySetting(int, Enum):
765    """An enum for players's privacy settings."""
766
767    OPEN = 0
768    CLAN_AND_FRIENDS = 1
769    FRIENDS_ONLY = 2
770    INVITE_ONLY = 3
771    CLOSED = 4

An enum for players's privacy settings.

OPEN = <PrivacySetting.OPEN: 0>
CLAN_AND_FRIENDS = <PrivacySetting.CLAN_AND_FRIENDS: 1>
FRIENDS_ONLY = <PrivacySetting.FRIENDS_ONLY: 2>
INVITE_ONLY = <PrivacySetting.INVITE_ONLY: 3>
CLOSED = <PrivacySetting.CLOSED: 4>
Inherited Members
Enum
name
value
class RESTClient(aiobungie.api.rest.RESTClient):
 430class RESTClient(api.RESTClient):
 431    """A single process REST client implementation.
 432
 433    This client is designed to only make HTTP requests and return raw JSON objects.
 434
 435    Example
 436    -------
 437    ```py
 438    import aiobungie
 439
 440    client = aiobungie.RESTClient("TOKEN")
 441    async with client:
 442        response = await client.fetch_clan_members(4389205)
 443        for member in response['results']:
 444            print(member['destinyUserInfo'])
 445    ```
 446
 447    Parameters
 448    ----------
 449    token : `str`
 450        A valid application token from Bungie's developer portal.
 451
 452    Other Parameters
 453    ----------------
 454    client_secret : `str | None`
 455        An optional application client secret,
 456        This is only needed if you're fetching OAuth2 tokens with this client.
 457    client_id : `int | None`
 458        An optional application client id,
 459        This is only needed if you're fetching OAuth2 tokens with this client.
 460    settings: `aiobungie.builders.Settings | None`
 461        The client settings to use, if `None` the default will be used.
 462    owned_client: `bool`
 463        * If set to `True`, this client will use the provided `client_session` parameter instead,
 464        * If set to `True` and `client_session` is `None`, `ValueError` will be raised.
 465        * If set to `False`, aiobungie will initialize a new client session for you.
 466
 467    client_session: `aiohttp.ClientSession | None`
 468        If provided, this client session will be used to make all the HTTP requests.
 469        The `owned_client` must be set to `True` for this to work.
 470    max_retries : `int`
 471        The max retries number to retry if the request hit a `5xx` status code.
 472    debug : `bool | str`
 473        Whether to enable logging responses or not.
 474
 475    Logging Levels
 476    --------------
 477    * `False`: This will disable logging.
 478    * `True`: This will set the level to `DEBUG` and enable logging minimal information.
 479    * `"TRACE" | aiobungie.TRACE`: This will log the response headers along with the minimal information.
 480    """
 481
 482    __slots__ = (
 483        "_token",
 484        "_session",
 485        "_lock",
 486        "_max_retries",
 487        "_client_secret",
 488        "_client_id",
 489        "_metadata",
 490        "_dumps",
 491        "_loads",
 492        "_owned_client",
 493        "_settings",
 494    )
 495
 496    def __init__(
 497        self,
 498        token: str,
 499        /,
 500        *,
 501        client_secret: str | None = None,
 502        client_id: int | None = None,
 503        settings: builders.Settings | None = None,
 504        owned_client: bool = True,
 505        client_session: aiohttp.ClientSession | None = None,
 506        dumps: typedefs.Dumps = helpers.dumps,
 507        loads: typedefs.Loads = helpers.loads,
 508        max_retries: int = 4,
 509        debug: typing.Literal["TRACE"] | bool | int = False,
 510    ) -> None:
 511        if owned_client is False and client_session is None:
 512            raise ValueError(
 513                "Expected an owned client session, but got `None`, Cannot have `owned_client` set to `False` and `client_session` to `None`"
 514            )
 515
 516        self._settings = settings or builders.Settings()
 517        self._session = client_session
 518        self._owned_client = owned_client
 519        self._lock: asyncio.Lock | None = None
 520        self._client_secret = client_secret
 521        self._client_id = client_id
 522        self._token: str = token
 523        self._max_retries = max_retries
 524        self._dumps = dumps
 525        self._loads = loads
 526        self._metadata: collections.MutableMapping[typing.Any, typing.Any] = {}
 527        self.with_debug(debug)
 528
 529    @property
 530    def client_id(self) -> int | None:
 531        return self._client_id
 532
 533    @property
 534    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
 535        return self._metadata
 536
 537    @property
 538    def is_alive(self) -> bool:
 539        return self._session is not None
 540
 541    @property
 542    def settings(self) -> builders.Settings:
 543        return self._settings
 544
 545    async def close(self) -> None:
 546        if self._session is None:
 547            raise RuntimeError("REST client is not running.")
 548
 549        if self._owned_client:
 550            await self._session.close()
 551            self._session = None
 552
 553    def open(self) -> None:
 554        """Open a new client session. This is called internally with contextmanager usage."""
 555        if self.is_alive and self._owned_client:
 556            raise RuntimeError("Cannot open REST client when it's already open.")
 557
 558        if self._owned_client:
 559            self._session = aiohttp.ClientSession(
 560                connector=aiohttp.TCPConnector(
 561                    use_dns_cache=self._settings.use_dns_cache,
 562                    ttl_dns_cache=self._settings.ttl_dns_cache,
 563                    ssl_context=self._settings.ssl_context,
 564                    ssl=self._settings.ssl,
 565                ),
 566                connector_owner=True,
 567                raise_for_status=False,
 568                timeout=self._settings.http_timeout,
 569                trust_env=self._settings.trust_env,
 570                headers=self._settings.headers,
 571            )
 572
 573    @typing.final
 574    async def static_request(
 575        self,
 576        method: _HTTP_METHOD,
 577        path: str,
 578        *,
 579        auth: str | None = None,
 580        json: collections.Mapping[str, typing.Any] | None = None,
 581        params: collections.Mapping[str, typing.Any] | None = None,
 582    ) -> typedefs.JSONIsh:
 583        return await self._request(method, path, auth=auth, json=json, params=params)
 584
 585    @typing.overload
 586    def build_oauth2_url(self, client_id: int) -> builders.OAuthURL: ...
 587
 588    @typing.overload
 589    def build_oauth2_url(self) -> builders.OAuthURL | None: ...
 590
 591    @typing.final
 592    def build_oauth2_url(
 593        self, client_id: int | None = None
 594    ) -> builders.OAuthURL | None:
 595        client_id = client_id or self._client_id
 596        if client_id is None:
 597            return None
 598
 599        return builders.OAuthURL(client_id=client_id)
 600
 601    @typing.final
 602    async def _request(
 603        self,
 604        method: _HTTP_METHOD,
 605        route: str,
 606        *,
 607        base: bool = False,
 608        oauth2: bool = False,
 609        auth: str | None = None,
 610        unwrap_bytes: bool = False,
 611        json: collections.Mapping[str, typing.Any] | None = None,
 612        data: collections.Mapping[str, typing.Any] | None = None,
 613        params: collections.Mapping[str, typing.Any] | None = None,
 614    ) -> typedefs.JSONIsh:
 615        # This is not None when opening the client.
 616        assert self._session is not None, (
 617            "This client hasn't been opened yet. Use `async with client` or `async with client.rest` "
 618            "before performing any request."
 619        )
 620
 621        retries: int = 0
 622        headers: collections.MutableMapping[str, typing.Any] = {}
 623
 624        headers[_USER_AGENT_HEADERS] = _USER_AGENT
 625        headers["X-API-KEY"] = self._token
 626
 627        if auth is not None:
 628            headers[_AUTH_HEADER] = f"Bearer {auth}"
 629
 630        # Handling endpoints
 631        endpoint = url.BASE
 632
 633        if not base:
 634            endpoint = endpoint + url.REST_EP
 635
 636        if oauth2:
 637            assert self._client_id, "Client ID is required to make authorized requests."
 638            assert self._client_secret, (
 639                "Client secret is required to make authorized requests."
 640            )
 641            headers["client_secret"] = self._client_secret
 642
 643            headers["Content-Type"] = "application/x-www-form-urlencoded"
 644            endpoint = endpoint + url.TOKEN_EP
 645
 646        if self._lock is None:
 647            self._lock = asyncio.Lock()
 648
 649        if json:
 650            headers["Content-Type"] = _APP_JSON
 651
 652        stack = contextlib.AsyncExitStack()
 653        while True:
 654            try:
 655                await stack.enter_async_context(self._lock)
 656
 657                # We make the request here.
 658                taken_time = time.monotonic()
 659                response = await self._session.request(
 660                    method=method,
 661                    url=f"{endpoint}/{route}",
 662                    headers=headers,
 663                    data=_JSONPayload(json) if json else data,
 664                    params=params,
 665                )
 666                response_time = (time.monotonic() - taken_time) * 1_000
 667
 668                _LOGGER.debug(
 669                    "METHOD: %s ROUTE: %s STATUS: %i ELAPSED: %.4fms",
 670                    method,
 671                    f"{endpoint}/{route}",
 672                    response.status,
 673                    response_time,
 674                )
 675
 676                await self._handle_ratelimit(response, method, route)
 677
 678            except aiohttp.ClientConnectionError as exc:
 679                if retries >= self._max_retries:
 680                    raise error.HTTPError(
 681                        str(exc),
 682                        http.HTTPStatus.SERVICE_UNAVAILABLE,
 683                    )
 684                backoff_ = backoff.ExponentialBackOff(maximum=8)
 685
 686                timer = next(backoff_)
 687                _LOGGER.warning(
 688                    "Client received a connection error <%s> Retrying in %.2fs. Remaining retries: %s",
 689                    type(exc).__qualname__,
 690                    timer,
 691                    self._max_retries - retries,
 692                )
 693                retries += 1
 694                await asyncio.sleep(timer)
 695                continue
 696
 697            finally:
 698                await stack.aclose()
 699
 700            if response.status == http.HTTPStatus.NO_CONTENT:
 701                return None
 702
 703            # Handle the successful response.
 704            if 300 > response.status >= 200:
 705                if unwrap_bytes:
 706                    # We need to read the bytes for the manifest response.
 707                    return await response.read()
 708
 709                # Bungie get funky and return HTML instead of JSON when making an authorized
 710                # request with a dummy access token. We could technically read the page content
 711                # but that's Bungie's fault for not returning a JSON response.
 712                if response.content_type != _APP_JSON:
 713                    raise error.HTTPError(
 714                        message=f"Expected JSON response, Got {response.content_type}, "
 715                        f"{response.real_url.human_repr()}",
 716                        http_status=http.HTTPStatus(response.status),
 717                    )
 718
 719                json_data = self._loads(await response.read())
 720
 721                if _LOGGER.isEnabledFor(TRACE):
 722                    _LOGGER.log(
 723                        TRACE,
 724                        "%s",
 725                        error.stringify_headers(dict(response.headers)),
 726                    )
 727
 728                    details: collections.MutableMapping[str, typing.Any] = {}
 729                    if json:
 730                        details["json"] = error.filtered_headers(json)
 731
 732                    if data:
 733                        details["data"] = error.filtered_headers(data)
 734
 735                    if params:
 736                        details["params"] = error.filtered_headers(params)
 737
 738                    if details:
 739                        _LOGGER.log(TRACE, "%s", error.stringify_headers(details))
 740
 741                # Return the response.
 742                # auth responses are not inside a Response object.
 743                if oauth2:
 744                    return json_data
 745
 746                # The reason we have a type ignore is because the actual response type
 747                # is within this `Response` key.
 748                return json_data["Response"]  # type: ignore
 749
 750            if (
 751                response.status in _RETRY_5XX and retries < self._max_retries  # noqa: W503
 752            ):
 753                backoff_ = backoff.ExponentialBackOff(maximum=6)
 754                sleep_time = next(backoff_)
 755                _LOGGER.warning(
 756                    "Got %i - %s. Sleeping for %.2f seconds. Remaining retries: %i",
 757                    response.status,
 758                    response.reason,
 759                    sleep_time,
 760                    self._max_retries - retries,
 761                )
 762
 763                retries += 1
 764                await asyncio.sleep(sleep_time)
 765                continue
 766
 767            raise await error.panic(response)
 768
 769    async def __aenter__(self) -> RESTClient:
 770        self.open()
 771        return self
 772
 773    async def __aexit__(
 774        self,
 775        exception_type: type[BaseException] | None,
 776        exception: BaseException | None,
 777        exception_traceback: types.TracebackType | None,
 778    ) -> None:
 779        await self.close()
 780
 781    # We don't want this to be super complicated.
 782    async def _handle_ratelimit(
 783        self,
 784        response: aiohttp.ClientResponse,
 785        method: str,
 786        route: str,
 787    ) -> None:
 788        if response.status != http.HTTPStatus.TOO_MANY_REQUESTS:
 789            return
 790
 791        if response.content_type != _APP_JSON:
 792            raise error.HTTPError(
 793                f"Being ratelimited on non JSON request, {response.content_type}.",
 794                http.HTTPStatus.TOO_MANY_REQUESTS,
 795            )
 796
 797        # The reason we have a type ignore here is that we guaranteed the content type is JSON above.
 798        json: typedefs.JSONObject = self._loads(await response.read())  # type: ignore
 799        retry_after = float(json.get("ThrottleSeconds", 15.0)) + 0.1
 800        max_calls: int = 0
 801
 802        while True:
 803            if max_calls == 10:
 804                # Max retries by default. We raise an error here.
 805                raise error.RateLimitedError(
 806                    body=json,
 807                    url=str(response.real_url),
 808                    retry_after=retry_after,
 809                )
 810
 811            # We sleep for a little bit to avoid funky behavior.
 812            _LOGGER.warning(
 813                "We're being ratelimited, Method %s Route %s. Sleeping for %.2fs.",
 814                method,
 815                route,
 816                retry_after,
 817            )
 818            await asyncio.sleep(retry_after)
 819            max_calls += 1
 820            continue
 821
 822    async def fetch_oauth2_tokens(self, code: str, /) -> builders.OAuth2Response:
 823        data = {
 824            "grant_type": "authorization_code",
 825            "code": code,
 826            "client_id": self._client_id,
 827            "client_secret": self._client_secret,
 828        }
 829
 830        response = await self._request(_POST, "", data=data, oauth2=True)
 831        assert isinstance(response, dict)
 832        return builders.OAuth2Response.build_response(response)
 833
 834    async def refresh_access_token(
 835        self, refresh_token: str, /
 836    ) -> builders.OAuth2Response:
 837        data = {
 838            "grant_type": "refresh_token",
 839            "refresh_token": refresh_token,
 840            "client_id": self._client_id,
 841            "client_secret": self._client_secret,
 842        }
 843
 844        response = await self._request(_POST, "", data=data, oauth2=True)
 845        assert isinstance(response, dict)
 846        return builders.OAuth2Response.build_response(response)
 847
 848    async def fetch_bungie_user(self, id: int) -> typedefs.JSONObject:
 849        resp = await self._request(_GET, f"User/GetBungieNetUserById/{id}/")
 850        assert isinstance(resp, dict)
 851        return resp
 852
 853    async def fetch_user_themes(self) -> typedefs.JSONArray:
 854        resp = await self._request(_GET, "User/GetAvailableThemes/")
 855        assert isinstance(resp, list)
 856        return resp
 857
 858    async def fetch_membership_from_id(
 859        self,
 860        id: int,
 861        type: enums.MembershipType | int = enums.MembershipType.NONE,
 862        /,
 863    ) -> typedefs.JSONObject:
 864        resp = await self._request(_GET, f"User/GetMembershipsById/{id}/{int(type)}")
 865        assert isinstance(resp, dict)
 866        return resp
 867
 868    async def fetch_membership(
 869        self,
 870        name: str,
 871        code: int,
 872        type: enums.MembershipType | int = enums.MembershipType.ALL,
 873        /,
 874    ) -> typedefs.JSONArray:
 875        resp = await self._request(
 876            _POST,
 877            f"Destiny2/SearchDestinyPlayerByBungieName/{int(type)}",
 878            json={"displayName": name, "displayNameCode": code},
 879        )
 880        assert isinstance(resp, list)
 881        return resp
 882
 883    async def fetch_sanitized_membership(
 884        self, membership_id: int, /
 885    ) -> typedefs.JSONObject:
 886        response = await self._request(
 887            _GET, f"User/GetSanitizedPlatformDisplayNames/{membership_id}/"
 888        )
 889        assert isinstance(response, dict)
 890        return response
 891
 892    async def search_users(self, name: str, /) -> typedefs.JSONObject:
 893        resp = await self._request(
 894            _POST,
 895            "User/Search/GlobalName/0",
 896            json={"displayNamePrefix": name},
 897        )
 898        assert isinstance(resp, dict)
 899        return resp
 900
 901    async def fetch_clan_from_id(
 902        self, id: int, /, access_token: str | None = None
 903    ) -> typedefs.JSONObject:
 904        resp = await self._request(_GET, f"GroupV2/{id}", auth=access_token)
 905        assert isinstance(resp, dict)
 906        return resp
 907
 908    async def fetch_clan(
 909        self,
 910        name: str,
 911        /,
 912        access_token: str | None = None,
 913        *,
 914        type: enums.GroupType | int = enums.GroupType.CLAN,
 915    ) -> typedefs.JSONObject:
 916        resp = await self._request(
 917            _GET, f"GroupV2/Name/{name}/{int(type)}", auth=access_token
 918        )
 919        assert isinstance(resp, dict)
 920        return resp
 921
 922    async def search_group(
 923        self,
 924        name: str,
 925        group_type: enums.GroupType | int = enums.GroupType.CLAN,
 926        *,
 927        creation_date: clans.GroupDate | int = 0,
 928        sort_by: int | None = None,
 929        group_member_count_filter: typing.Literal[0, 1, 2, 3] | None = None,
 930        locale_filter: str | None = None,
 931        tag_text: str | None = None,
 932        items_per_page: int | None = None,
 933        current_page: int | None = None,
 934        request_token: str | None = None,
 935    ) -> typedefs.JSONObject:
 936        payload: collections.MutableMapping[str, typing.Any] = {"name": name}
 937
 938        # as the official documentation says, you're not allowed to use those fields
 939        # on a clan search. it is safe to send the request with them being `null` but not filled with a value.
 940        if (
 941            group_type == enums.GroupType.CLAN
 942            and group_member_count_filter is not None
 943            and locale_filter
 944            and tag_text
 945        ):
 946            raise ValueError(
 947                "If you're searching for clans, (group_member_count_filter, locale_filter, tag_text) must be None."
 948            )
 949
 950        payload["groupType"] = int(group_type)
 951        payload["creationDate"] = int(creation_date)
 952        payload["sortBy"] = sort_by
 953        payload["groupMemberCount"] = group_member_count_filter
 954        payload["locale"] = locale_filter
 955        payload["tagText"] = tag_text
 956        payload["itemsPerPage"] = items_per_page
 957        payload["currentPage"] = current_page
 958        payload["requestToken"] = request_token
 959        payload["requestContinuationToken"] = request_token
 960
 961        resp = await self._request(_POST, "GroupV2/Search/", json=payload)
 962        assert isinstance(resp, dict)
 963        return resp
 964
 965    async def fetch_clan_admins(self, clan_id: int, /) -> typedefs.JSONObject:
 966        resp = await self._request(_GET, f"GroupV2/{clan_id}/AdminsAndFounder/")
 967        assert isinstance(resp, dict)
 968        return resp
 969
 970    async def fetch_clan_conversations(self, clan_id: int, /) -> typedefs.JSONArray:
 971        resp = await self._request(_GET, f"GroupV2/{clan_id}/OptionalConversations/")
 972        assert isinstance(resp, list)
 973        return resp
 974
 975    async def fetch_application(self, appid: int, /) -> typedefs.JSONObject:
 976        resp = await self._request(_GET, f"App/Application/{appid}")
 977        assert isinstance(resp, dict)
 978        return resp
 979
 980    async def fetch_character(
 981        self,
 982        member_id: int,
 983        membership_type: enums.MembershipType | int,
 984        character_id: int,
 985        components: collections.Sequence[enums.ComponentType],
 986        auth: str | None = None,
 987    ) -> typedefs.JSONObject:
 988        collector = _collect_components(components)
 989        response = await self._request(
 990            _GET,
 991            f"Destiny2/{int(membership_type)}/Profile/{member_id}/"
 992            f"Character/{character_id}/?components={collector}",
 993            auth=auth,
 994        )
 995        assert isinstance(response, dict)
 996        return response
 997
 998    async def fetch_activities(
 999        self,
1000        member_id: int,
1001        character_id: int,
1002        mode: enums.GameMode | int,
1003        membership_type: enums.MembershipType | int = enums.MembershipType.ALL,
1004        *,
1005        page: int = 0,
1006        limit: int = 1,
1007    ) -> typedefs.JSONObject:
1008        resp = await self._request(
1009            _GET,
1010            f"Destiny2/{int(membership_type)}/Account/"
1011            f"{member_id}/Character/{character_id}/Stats/Activities"
1012            f"/?mode={int(mode)}&count={limit}&page={page}",
1013        )
1014        assert isinstance(resp, dict)
1015        return resp
1016
1017    async def fetch_vendor_sales(self) -> typedefs.JSONObject:
1018        resp = await self._request(
1019            _GET,
1020            f"Destiny2/Vendors/?components={int(enums.ComponentType.VENDOR_SALES)}",
1021        )
1022        assert isinstance(resp, dict)
1023        return resp
1024
1025    async def fetch_profile(
1026        self,
1027        membership_id: int,
1028        type: enums.MembershipType | int,
1029        components: collections.Sequence[enums.ComponentType],
1030        auth: str | None = None,
1031    ) -> typedefs.JSONObject:
1032        collector = _collect_components(components)
1033        response = await self._request(
1034            _GET,
1035            f"Destiny2/{int(type)}/Profile/{membership_id}/?components={collector}",
1036            auth=auth,
1037        )
1038        assert isinstance(response, dict)
1039        return response
1040
1041    async def fetch_entity(self, type: str, hash: int) -> typedefs.JSONObject:
1042        response = await self._request(_GET, route=f"Destiny2/Manifest/{type}/{hash}")
1043        assert isinstance(response, dict)
1044        return response
1045
1046    async def fetch_inventory_item(self, hash: int, /) -> typedefs.JSONObject:
1047        resp = await self.fetch_entity("DestinyInventoryItemDefinition", hash)
1048        assert isinstance(resp, dict)
1049        return resp
1050
1051    async def fetch_objective_entity(self, hash: int, /) -> typedefs.JSONObject:
1052        resp = await self.fetch_entity("DestinyObjectiveDefinition", hash)
1053        assert isinstance(resp, dict)
1054        return resp
1055
1056    async def fetch_groups_for_member(
1057        self,
1058        member_id: int,
1059        member_type: enums.MembershipType | int,
1060        /,
1061        *,
1062        filter: int = 0,
1063        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1064    ) -> typedefs.JSONObject:
1065        resp = await self._request(
1066            _GET,
1067            f"GroupV2/User/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1068        )
1069        assert isinstance(resp, dict)
1070        return resp
1071
1072    async def fetch_potential_groups_for_member(
1073        self,
1074        member_id: int,
1075        member_type: enums.MembershipType | int,
1076        /,
1077        *,
1078        filter: int = 0,
1079        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1080    ) -> typedefs.JSONObject:
1081        resp = await self._request(
1082            _GET,
1083            f"GroupV2/User/Potential/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1084        )
1085        assert isinstance(resp, dict)
1086        return resp
1087
1088    async def fetch_clan_members(
1089        self,
1090        clan_id: int,
1091        /,
1092        *,
1093        name: str | None = None,
1094        type: enums.MembershipType | int = enums.MembershipType.NONE,
1095    ) -> typedefs.JSONObject:
1096        resp = await self._request(
1097            _GET,
1098            f"/GroupV2/{clan_id}/Members/?memberType={int(type)}&nameSearch={name if name else ''}&currentpage=1",
1099        )
1100        assert isinstance(resp, dict)
1101        return resp
1102
1103    async def fetch_hardlinked_credentials(
1104        self,
1105        credential: int,
1106        type: enums.CredentialType | int = enums.CredentialType.STEAMID,
1107        /,
1108    ) -> typedefs.JSONObject:
1109        resp = await self._request(
1110            _GET,
1111            f"User/GetMembershipFromHardLinkedCredential/{int(type)}/{credential}/",
1112        )
1113        assert isinstance(resp, dict)
1114        return resp
1115
1116    async def fetch_user_credentials(
1117        self, access_token: str, membership_id: int, /
1118    ) -> typedefs.JSONArray:
1119        resp = await self._request(
1120            _GET,
1121            f"User/GetCredentialTypesForTargetAccount/{membership_id}",
1122            auth=access_token,
1123        )
1124        assert isinstance(resp, list)
1125        return resp
1126
1127    async def insert_socket_plug(
1128        self,
1129        action_token: str,
1130        /,
1131        instance_id: int,
1132        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1133        character_id: int,
1134        membership_type: enums.MembershipType | int,
1135    ) -> typedefs.JSONObject:
1136        if isinstance(plug, builders.PlugSocketBuilder):
1137            plug = plug.collect()
1138
1139        body = {
1140            "actionToken": action_token,
1141            "itemInstanceId": instance_id,
1142            "plug": plug,
1143            "characterId": character_id,
1144            "membershipType": int(membership_type),
1145        }
1146        resp = await self._request(
1147            _POST, "Destiny2/Actions/Items/InsertSocketPlug", json=body
1148        )
1149        assert isinstance(resp, dict)
1150        return resp
1151
1152    async def insert_socket_plug_free(
1153        self,
1154        access_token: str,
1155        /,
1156        instance_id: int,
1157        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1158        character_id: int,
1159        membership_type: enums.MembershipType | int,
1160    ) -> typedefs.JSONObject:
1161        if isinstance(plug, builders.PlugSocketBuilder):
1162            plug = plug.collect()
1163
1164        body = {
1165            "itemInstanceId": instance_id,
1166            "plug": plug,
1167            "characterId": character_id,
1168            "membershipType": int(membership_type),
1169        }
1170        resp = await self._request(
1171            _POST,
1172            "Destiny2/Actions/Items/InsertSocketPlugFree",
1173            json=body,
1174            auth=access_token,
1175        )
1176        assert isinstance(resp, dict)
1177        return resp
1178
1179    @helpers.unstable
1180    async def set_item_lock_state(
1181        self,
1182        access_token: str,
1183        state: bool,
1184        /,
1185        item_id: int,
1186        character_id: int,
1187        membership_type: enums.MembershipType | int,
1188    ) -> int:
1189        body = {
1190            "state": state,
1191            "itemId": item_id,
1192            "characterId": character_id,
1193            "membershipType": int(membership_type),
1194        }
1195        response = await self._request(
1196            _POST,
1197            "Destiny2/Actions/Items/SetLockState",
1198            json=body,
1199            auth=access_token,
1200        )
1201        assert isinstance(response, int)
1202        return response
1203
1204    async def set_quest_track_state(
1205        self,
1206        access_token: str,
1207        state: bool,
1208        /,
1209        item_id: int,
1210        character_id: int,
1211        membership_type: enums.MembershipType | int,
1212    ) -> int:
1213        body = {
1214            "state": state,
1215            "itemId": item_id,
1216            "characterId": character_id,
1217            "membership_type": int(membership_type),
1218        }
1219        response = await self._request(
1220            _POST,
1221            "Destiny2/Actions/Items/SetTrackedState",
1222            json=body,
1223            auth=access_token,
1224        )
1225        assert isinstance(response, int)
1226        return response
1227
1228    async def fetch_manifest_path(self) -> typedefs.JSONObject:
1229        path = await self._request(_GET, "Destiny2/Manifest")
1230        assert isinstance(path, dict)
1231        return path
1232
1233    async def read_manifest_bytes(self, language: _ALLOWED_LANGS = "en", /) -> bytes:
1234        _ensure_manifest_language(language)
1235
1236        content = await self.fetch_manifest_path()
1237        resp = await self._request(
1238            _GET,
1239            content["mobileWorldContentPaths"][language],
1240            unwrap_bytes=True,
1241            base=True,
1242        )
1243        assert isinstance(resp, bytes)
1244        return resp
1245
1246    async def download_sqlite_manifest(
1247        self,
1248        language: _ALLOWED_LANGS = "en",
1249        name: str = "manifest",
1250        path: pathlib.Path | str = ".",
1251        *,
1252        force: bool = False,
1253        executor: concurrent.futures.Executor | None = None,
1254    ) -> pathlib.Path:
1255        complete_path = _get_path(name, path, sql=True)
1256
1257        if complete_path.exists():
1258            if force:
1259                _LOGGER.info(
1260                    f"Found manifest in {complete_path!s}. Forcing to Re-Download."
1261                )
1262                complete_path.unlink(missing_ok=True)
1263
1264                return await self.download_sqlite_manifest(
1265                    language, name, path, force=force
1266                )
1267
1268            else:
1269                raise FileExistsError(
1270                    "Manifest file already exists, "
1271                    "To force download, set the `force` parameter to `True`."
1272                )
1273
1274        _LOGGER.info(f"Downloading manifest. Location: {complete_path!s}")
1275        data_bytes = await self.read_manifest_bytes(language)
1276        await asyncio.get_running_loop().run_in_executor(
1277            executor, _write_sqlite_bytes, data_bytes, path, name
1278        )
1279        _LOGGER.info("Finished downloading manifest.")
1280        return _get_path(name, path, sql=True)
1281
1282    async def download_json_manifest(
1283        self,
1284        file_name: str = "manifest",
1285        path: str | pathlib.Path = ".",
1286        *,
1287        language: _ALLOWED_LANGS = "en",
1288        executor: concurrent.futures.Executor | None = None,
1289    ) -> pathlib.Path:
1290        _ensure_manifest_language(language)
1291        full_path = _get_path(file_name, path)
1292        _LOGGER.info(f"Downloading manifest JSON to {full_path!r}...")
1293
1294        content = await self.fetch_manifest_path()
1295        json_bytes = await self._request(
1296            _GET,
1297            content["jsonWorldContentPaths"][language],
1298            unwrap_bytes=True,
1299            base=True,
1300        )
1301
1302        assert isinstance(json_bytes, bytes)
1303        await asyncio.get_running_loop().run_in_executor(
1304            executor, _write_json_bytes, json_bytes, file_name, path
1305        )
1306        _LOGGER.info("Finished downloading manifest JSON.")
1307        return full_path
1308
1309    async def fetch_manifest_version(self) -> str:
1310        # This is guaranteed str.
1311        return (await self.fetch_manifest_path())["version"]
1312
1313    async def fetch_linked_profiles(
1314        self,
1315        member_id: int,
1316        member_type: enums.MembershipType | int,
1317        /,
1318        *,
1319        all: bool = False,
1320    ) -> typedefs.JSONObject:
1321        resp = await self._request(
1322            _GET,
1323            f"Destiny2/{int(member_type)}/Profile/{member_id}/LinkedProfiles/?getAllMemberships={all}",
1324        )
1325        assert isinstance(resp, dict)
1326        return resp
1327
1328    async def fetch_clan_banners(self) -> typedefs.JSONObject:
1329        resp = await self._request(_GET, "Destiny2/Clan/ClanBannerDictionary/")
1330        assert isinstance(resp, dict)
1331        return resp
1332
1333    async def fetch_public_milestones(self) -> typedefs.JSONObject:
1334        resp = await self._request(_GET, "Destiny2/Milestones/")
1335        assert isinstance(resp, dict)
1336        return resp
1337
1338    async def fetch_public_milestone_content(
1339        self, milestone_hash: int, /
1340    ) -> typedefs.JSONObject:
1341        resp = await self._request(
1342            _GET, f"Destiny2/Milestones/{milestone_hash}/Content/"
1343        )
1344        assert isinstance(resp, dict)
1345        return resp
1346
1347    async def fetch_current_user_memberships(
1348        self, access_token: str, /
1349    ) -> typedefs.JSONObject:
1350        resp = await self._request(
1351            _GET,
1352            "User/GetMembershipsForCurrentUser/",
1353            auth=access_token,
1354        )
1355        assert isinstance(resp, dict)
1356        return resp
1357
1358    async def equip_item(
1359        self,
1360        access_token: str,
1361        /,
1362        item_id: int,
1363        character_id: int,
1364        membership_type: enums.MembershipType | int,
1365    ) -> None:
1366        payload = {
1367            "itemId": item_id,
1368            "characterId": character_id,
1369            "membershipType": int(membership_type),
1370        }
1371
1372        await self._request(
1373            _POST,
1374            "Destiny2/Actions/Items/EquipItem/",
1375            json=payload,
1376            auth=access_token,
1377        )
1378
1379    async def equip_items(
1380        self,
1381        access_token: str,
1382        /,
1383        item_ids: collections.Sequence[int],
1384        character_id: int,
1385        membership_type: enums.MembershipType | int,
1386    ) -> None:
1387        payload = {
1388            "itemIds": item_ids,
1389            "characterId": character_id,
1390            "membershipType": int(membership_type),
1391        }
1392        await self._request(
1393            _POST,
1394            "Destiny2/Actions/Items/EquipItems/",
1395            json=payload,
1396            auth=access_token,
1397        )
1398
1399    async def ban_clan_member(
1400        self,
1401        access_token: str,
1402        /,
1403        group_id: int,
1404        membership_id: int,
1405        membership_type: enums.MembershipType | int,
1406        *,
1407        length: int = 0,
1408        comment: str | None = None,
1409    ) -> None:
1410        payload = {"comment": str(comment), "length": length}
1411        await self._request(
1412            _POST,
1413            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Ban/",
1414            json=payload,
1415            auth=access_token,
1416        )
1417
1418    async def unban_clan_member(
1419        self,
1420        access_token: str,
1421        /,
1422        group_id: int,
1423        membership_id: int,
1424        membership_type: enums.MembershipType | int,
1425    ) -> None:
1426        await self._request(
1427            _POST,
1428            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Unban/",
1429            auth=access_token,
1430        )
1431
1432    async def kick_clan_member(
1433        self,
1434        access_token: str,
1435        /,
1436        group_id: int,
1437        membership_id: int,
1438        membership_type: enums.MembershipType | int,
1439    ) -> typedefs.JSONObject:
1440        resp = await self._request(
1441            _POST,
1442            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Kick/",
1443            auth=access_token,
1444        )
1445        assert isinstance(resp, dict)
1446        return resp
1447
1448    async def edit_clan(
1449        self,
1450        access_token: str,
1451        /,
1452        group_id: int,
1453        *,
1454        name: str | None = None,
1455        about: str | None = None,
1456        motto: str | None = None,
1457        theme: str | None = None,
1458        tags: collections.Sequence[str] | None = None,
1459        is_public: bool | None = None,
1460        locale: str | None = None,
1461        avatar_image_index: int | None = None,
1462        membership_option: enums.MembershipOption | int | None = None,
1463        allow_chat: bool | None = None,
1464        chat_security: typing.Literal[0, 1] | None = None,
1465        call_sign: str | None = None,
1466        homepage: typing.Literal[0, 1, 2] | None = None,
1467        enable_invite_messaging_for_admins: bool | None = None,
1468        default_publicity: typing.Literal[0, 1, 2] | None = None,
1469        is_public_topic_admin: bool | None = None,
1470    ) -> None:
1471        payload = {
1472            "name": name,
1473            "about": about,
1474            "motto": motto,
1475            "theme": theme,
1476            "tags": tags,
1477            "isPublic": is_public,
1478            "avatarImageIndex": avatar_image_index,
1479            "isPublicTopicAdminOnly": is_public_topic_admin,
1480            "allowChat": allow_chat,
1481            "chatSecurity": chat_security,
1482            "callsign": call_sign,
1483            "homepage": homepage,
1484            "enableInvitationMessagingForAdmins": enable_invite_messaging_for_admins,
1485            "defaultPublicity": default_publicity,
1486            "locale": locale,
1487        }
1488        if membership_option is not None:
1489            payload["membershipOption"] = int(membership_option)
1490
1491        await self._request(
1492            _POST,
1493            f"GroupV2/{group_id}/Edit",
1494            json=payload,
1495            auth=access_token,
1496        )
1497
1498    async def edit_clan_options(
1499        self,
1500        access_token: str,
1501        /,
1502        group_id: int,
1503        *,
1504        invite_permissions_override: bool | None = None,
1505        update_culture_permissionOverride: bool | None = None,
1506        host_guided_game_permission_override: typing.Literal[0, 1, 2] | None = None,
1507        update_banner_permission_override: bool | None = None,
1508        join_level: enums.ClanMemberType | int | None = None,
1509    ) -> None:
1510        payload = {
1511            "InvitePermissionOverride": invite_permissions_override,
1512            "UpdateCulturePermissionOverride": update_culture_permissionOverride,
1513            "HostGuidedGamePermissionOverride": host_guided_game_permission_override,
1514            "UpdateBannerPermissionOverride": update_banner_permission_override,
1515            "JoinLevel": int(join_level) if join_level else None,
1516        }
1517
1518        await self._request(
1519            _POST,
1520            f"GroupV2/{group_id}/EditFounderOptions",
1521            json=payload,
1522            auth=access_token,
1523        )
1524
1525    async def report_player(
1526        self,
1527        access_token: str,
1528        /,
1529        activity_id: int,
1530        character_id: int,
1531        reason_hashes: collections.Sequence[int],
1532        reason_category_hashes: collections.Sequence[int],
1533    ) -> None:
1534        await self._request(
1535            _POST,
1536            f"Destiny2/Stats/PostGameCarnageReport/{activity_id}/Report/",
1537            json={
1538                "reasonCategoryHashes": reason_category_hashes,
1539                "reasonHashes": reason_hashes,
1540                "offendingCharacterId": character_id,
1541            },
1542            auth=access_token,
1543        )
1544
1545    async def fetch_friends(self, access_token: str, /) -> typedefs.JSONObject:
1546        resp = await self._request(
1547            _GET,
1548            "Social/Friends/",
1549            auth=access_token,
1550        )
1551        assert isinstance(resp, dict)
1552        return resp
1553
1554    async def fetch_friend_requests(self, access_token: str, /) -> typedefs.JSONObject:
1555        resp = await self._request(
1556            _GET,
1557            "Social/Friends/Requests",
1558            auth=access_token,
1559        )
1560        assert isinstance(resp, dict)
1561        return resp
1562
1563    async def accept_friend_request(self, access_token: str, /, member_id: int) -> None:
1564        await self._request(
1565            _POST,
1566            f"Social/Friends/Requests/Accept/{member_id}",
1567            auth=access_token,
1568        )
1569
1570    async def send_friend_request(self, access_token: str, /, member_id: int) -> None:
1571        await self._request(
1572            _POST,
1573            f"Social/Friends/Add/{member_id}",
1574            auth=access_token,
1575        )
1576
1577    async def decline_friend_request(
1578        self, access_token: str, /, member_id: int
1579    ) -> None:
1580        await self._request(
1581            _POST,
1582            f"Social/Friends/Requests/Decline/{member_id}",
1583            auth=access_token,
1584        )
1585
1586    async def remove_friend(self, access_token: str, /, member_id: int) -> None:
1587        await self._request(
1588            _POST,
1589            f"Social/Friends/Remove/{member_id}",
1590            auth=access_token,
1591        )
1592
1593    async def remove_friend_request(self, access_token: str, /, member_id: int) -> None:
1594        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1595        await self._request(
1596            _POST,
1597            f"Social/Friends/Requests/Remove/{member_id}",
1598            auth=access_token,
1599        )
1600
1601    async def approve_all_pending_group_users(
1602        self,
1603        access_token: str,
1604        /,
1605        group_id: int,
1606        message: str | None = None,
1607    ) -> None:
1608        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1609        await self._request(
1610            _POST,
1611            f"GroupV2/{group_id}/Members/ApproveAll",
1612            auth=access_token,
1613            json={"message": str(message)},
1614        )
1615
1616    async def deny_all_pending_group_users(
1617        self,
1618        access_token: str,
1619        /,
1620        group_id: int,
1621        *,
1622        message: str | None = None,
1623    ) -> None:
1624        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1625        await self._request(
1626            _POST,
1627            f"GroupV2/{group_id}/Members/DenyAll",
1628            auth=access_token,
1629            json={"message": str(message)},
1630        )
1631
1632    async def add_optional_conversation(
1633        self,
1634        access_token: str,
1635        /,
1636        group_id: int,
1637        *,
1638        name: str | None = None,
1639        security: typing.Literal[0, 1] = 0,
1640    ) -> None:
1641        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1642        payload = {"chatName": str(name), "chatSecurity": security}
1643        await self._request(
1644            _POST,
1645            f"GroupV2/{group_id}/OptionalConversations/Add",
1646            json=payload,
1647            auth=access_token,
1648        )
1649
1650    async def edit_optional_conversation(
1651        self,
1652        access_token: str,
1653        /,
1654        group_id: int,
1655        conversation_id: int,
1656        *,
1657        name: str | None = None,
1658        security: typing.Literal[0, 1] = 0,
1659        enable_chat: bool = False,
1660    ) -> None:
1661        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1662        payload = {
1663            "chatEnabled": enable_chat,
1664            "chatName": str(name),
1665            "chatSecurity": security,
1666        }
1667        await self._request(
1668            _POST,
1669            f"GroupV2/{group_id}/OptionalConversations/Edit/{conversation_id}",
1670            json=payload,
1671            auth=access_token,
1672        )
1673
1674    async def transfer_item(
1675        self,
1676        access_token: str,
1677        /,
1678        item_id: int,
1679        item_hash: int,
1680        character_id: int,
1681        member_type: enums.MembershipType | int,
1682        *,
1683        stack_size: int = 1,
1684        vault: bool = False,
1685    ) -> None:
1686        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1687        payload = {
1688            "characterId": character_id,
1689            "membershipType": int(member_type),
1690            "itemId": item_id,
1691            "itemReferenceHash": item_hash,
1692            "stackSize": stack_size,
1693            "transferToVault": vault,
1694        }
1695        await self._request(
1696            _POST,
1697            "Destiny2/Actions/Items/TransferItem",
1698            json=payload,
1699            auth=access_token,
1700        )
1701
1702    async def pull_item(
1703        self,
1704        access_token: str,
1705        /,
1706        item_id: int,
1707        item_hash: int,
1708        character_id: int,
1709        member_type: enums.MembershipType | int,
1710        *,
1711        stack_size: int = 1,
1712        vault: bool = False,
1713    ) -> None:
1714        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1715        payload = {
1716            "characterId": character_id,
1717            "membershipType": int(member_type),
1718            "itemId": item_id,
1719            "itemReferenceHash": item_hash,
1720            "stackSize": stack_size,
1721        }
1722        await self._request(
1723            _POST,
1724            "Destiny2/Actions/Items/PullFromPostmaster",
1725            json=payload,
1726            auth=access_token,
1727        )
1728        if vault:
1729            await self.transfer_item(
1730                access_token,
1731                item_id=item_id,
1732                item_hash=item_hash,
1733                character_id=character_id,
1734                member_type=member_type,
1735                stack_size=stack_size,
1736                vault=True,
1737            )
1738
1739    @helpers.unstable
1740    async def fetch_fireteams(
1741        self,
1742        activity_type: fireteams.FireteamActivity | int,
1743        *,
1744        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1745        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1746        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1747        page: int = 0,
1748        slots_filter: int = 0,
1749    ) -> typedefs.JSONObject:
1750        resp = await self._request(
1751            _GET,
1752            f"Fireteam/Search/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{page}/?langFilter={str(language)}",  # noqa: E501 Line too long
1753        )
1754        assert isinstance(resp, dict)
1755        return resp
1756
1757    async def fetch_available_clan_fireteams(
1758        self,
1759        access_token: str,
1760        group_id: int,
1761        activity_type: fireteams.FireteamActivity | int,
1762        *,
1763        platform: fireteams.FireteamPlatform | int,
1764        language: fireteams.FireteamLanguage | str,
1765        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1766        page: int = 0,
1767        public_only: bool = False,
1768        slots_filter: int = 0,
1769    ) -> typedefs.JSONObject:
1770        resp = await self._request(
1771            _GET,
1772            f"Fireteam/Clan/{group_id}/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{public_only}/{page}",  # noqa: E501
1773            json={"langFilter": str(language)},
1774            auth=access_token,
1775        )
1776        assert isinstance(resp, dict)
1777        return resp
1778
1779    async def fetch_clan_fireteam(
1780        self, access_token: str, fireteam_id: int, group_id: int
1781    ) -> typedefs.JSONObject:
1782        resp = await self._request(
1783            _GET,
1784            f"Fireteam/Clan/{group_id}/Summary/{fireteam_id}",
1785            auth=access_token,
1786        )
1787        assert isinstance(resp, dict)
1788        return resp
1789
1790    async def fetch_my_clan_fireteams(
1791        self,
1792        access_token: str,
1793        group_id: int,
1794        *,
1795        include_closed: bool = True,
1796        platform: fireteams.FireteamPlatform | int,
1797        language: fireteams.FireteamLanguage | str,
1798        filtered: bool = True,
1799        page: int = 0,
1800    ) -> typedefs.JSONObject:
1801        payload = {"groupFilter": filtered, "langFilter": str(language)}
1802
1803        resp = await self._request(
1804            _GET,
1805            f"Fireteam/Clan/{group_id}/My/{int(platform)}/{include_closed}/{page}",
1806            json=payload,
1807            auth=access_token,
1808        )
1809        assert isinstance(resp, dict)
1810        return resp
1811
1812    async def fetch_private_clan_fireteams(
1813        self, access_token: str, group_id: int, /
1814    ) -> int:
1815        resp = await self._request(
1816            _GET,
1817            f"Fireteam/Clan/{group_id}/ActiveCount",
1818            auth=access_token,
1819        )
1820        assert isinstance(resp, int)
1821        return resp
1822
1823    async def fetch_post_activity(self, instance_id: int, /) -> typedefs.JSONObject:
1824        resp = await self._request(
1825            _GET, f"Destiny2/Stats/PostGameCarnageReport/{instance_id}"
1826        )
1827        assert isinstance(resp, dict)
1828        return resp
1829
1830    @helpers.unstable
1831    async def search_entities(
1832        self, name: str, entity_type: str, *, page: int = 0
1833    ) -> typedefs.JSONObject:
1834        resp = await self._request(
1835            _GET,
1836            f"Destiny2/Armory/Search/{entity_type}/{name}/",
1837            json={"page": page},
1838        )
1839        assert isinstance(resp, dict)
1840        return resp
1841
1842    async def fetch_unique_weapon_history(
1843        self,
1844        membership_id: int,
1845        character_id: int,
1846        membership_type: enums.MembershipType | int,
1847    ) -> typedefs.JSONObject:
1848        resp = await self._request(
1849            _GET,
1850            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/UniqueWeapons/",
1851        )
1852        assert isinstance(resp, dict)
1853        return resp
1854
1855    async def fetch_item(
1856        self,
1857        member_id: int,
1858        item_id: int,
1859        membership_type: enums.MembershipType | int,
1860        components: collections.Sequence[enums.ComponentType],
1861    ) -> typedefs.JSONObject:
1862        collector = _collect_components(components)
1863
1864        resp = await self._request(
1865            _GET,
1866            f"Destiny2/{int(membership_type)}/Profile/{member_id}/Item/{item_id}/?components={collector}",
1867        )
1868        assert isinstance(resp, dict)
1869        return resp
1870
1871    async def fetch_clan_weekly_rewards(self, clan_id: int, /) -> typedefs.JSONObject:
1872        resp = await self._request(_GET, f"Destiny2/Clan/{clan_id}/WeeklyRewardState/")
1873        assert isinstance(resp, dict)
1874        return resp
1875
1876    async def fetch_available_locales(self) -> typedefs.JSONObject:
1877        resp = await self._request(_GET, "Destiny2/Manifest/DestinyLocaleDefinition/")
1878        assert isinstance(resp, dict)
1879        return resp
1880
1881    async def fetch_common_settings(self) -> typedefs.JSONObject:
1882        resp = await self._request(_GET, "Settings")
1883        assert isinstance(resp, dict)
1884        return resp
1885
1886    async def fetch_user_systems_overrides(self) -> typedefs.JSONObject:
1887        resp = await self._request(_GET, "UserSystemOverrides")
1888        assert isinstance(resp, dict)
1889        return resp
1890
1891    async def fetch_global_alerts(
1892        self, *, include_streaming: bool = False
1893    ) -> typedefs.JSONArray:
1894        resp = await self._request(
1895            _GET, f"GlobalAlerts/?includestreaming={include_streaming}"
1896        )
1897        assert isinstance(resp, list)
1898        return resp
1899
1900    async def awainitialize_request(
1901        self,
1902        access_token: str,
1903        type: typing.Literal[0, 1],
1904        membership_type: enums.MembershipType | int,
1905        /,
1906        *,
1907        affected_item_id: int | None = None,
1908        character_id: int | None = None,
1909    ) -> typedefs.JSONObject:
1910        body = {"type": type, "membershipType": int(membership_type)}
1911
1912        if affected_item_id is not None:
1913            body["affectedItemId"] = affected_item_id
1914
1915        if character_id is not None:
1916            body["characterId"] = character_id
1917
1918        resp = await self._request(
1919            _POST, "Destiny2/Awa/Initialize", json=body, auth=access_token
1920        )
1921        assert isinstance(resp, dict)
1922        return resp
1923
1924    async def awaget_action_token(
1925        self, access_token: str, correlation_id: str, /
1926    ) -> typedefs.JSONObject:
1927        resp = await self._request(
1928            _POST,
1929            f"Destiny2/Awa/GetActionToken/{correlation_id}",
1930            auth=access_token,
1931        )
1932        assert isinstance(resp, dict)
1933        return resp
1934
1935    async def awa_provide_authorization_result(
1936        self,
1937        access_token: str,
1938        selection: int,
1939        correlation_id: str,
1940        nonce: collections.MutableSequence[str | bytes],
1941    ) -> int:
1942        body = {"selection": selection, "correlationId": correlation_id, "nonce": nonce}
1943
1944        resp = await self._request(
1945            _POST,
1946            "Destiny2/Awa/AwaProvideAuthorizationResult",
1947            json=body,
1948            auth=access_token,
1949        )
1950        assert isinstance(resp, int)
1951        return resp
1952
1953    async def fetch_vendors(
1954        self,
1955        access_token: str,
1956        character_id: int,
1957        membership_id: int,
1958        membership_type: enums.MembershipType | int,
1959        /,
1960        components: collections.Sequence[enums.ComponentType],
1961        filter: int | None = None,
1962    ) -> typedefs.JSONObject:
1963        components_ = _collect_components(components)
1964        route = (
1965            f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1966            f"/Character/{character_id}/Vendors/?components={components_}"
1967        )
1968
1969        if filter is not None:
1970            route = route + f"&filter={filter}"
1971
1972        resp = await self._request(
1973            _GET,
1974            route,
1975            auth=access_token,
1976        )
1977        assert isinstance(resp, dict)
1978        return resp
1979
1980    async def fetch_vendor(
1981        self,
1982        access_token: str,
1983        character_id: int,
1984        membership_id: int,
1985        membership_type: enums.MembershipType | int,
1986        vendor_hash: int,
1987        /,
1988        components: collections.Sequence[enums.ComponentType],
1989    ) -> typedefs.JSONObject:
1990        components_ = _collect_components(components)
1991        resp = await self._request(
1992            _GET,
1993            (
1994                f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1995                f"/Character/{character_id}/Vendors/{vendor_hash}/?components={components_}"
1996            ),
1997            auth=access_token,
1998        )
1999        assert isinstance(resp, dict)
2000        return resp
2001
2002    async def fetch_application_api_usage(
2003        self,
2004        access_token: str,
2005        application_id: int,
2006        /,
2007        *,
2008        start: datetime.datetime | None = None,
2009        end: datetime.datetime | None = None,
2010    ) -> typedefs.JSONObject:
2011        end_date, start_date = time.parse_date_range(end, start)
2012        resp = await self._request(
2013            _GET,
2014            f"App/ApiUsage/{application_id}/?end={end_date}&start={start_date}",
2015            auth=access_token,
2016        )
2017        assert isinstance(resp, dict)
2018        return resp
2019
2020    async def fetch_bungie_applications(self) -> typedefs.JSONArray:
2021        resp = await self._request(_GET, "App/FirstParty")
2022        assert isinstance(resp, list)
2023        return resp
2024
2025    async def fetch_content_type(self, type: str, /) -> typedefs.JSONObject:
2026        resp = await self._request(_GET, f"Content/GetContentType/{type}/")
2027        assert isinstance(resp, dict)
2028        return resp
2029
2030    async def fetch_content_by_id(
2031        self, id: int, locale: str, /, *, head: bool = False
2032    ) -> typedefs.JSONObject:
2033        resp = await self._request(
2034            _GET,
2035            f"Content/GetContentById/{id}/{locale}/",
2036            json={"head": head},
2037        )
2038        assert isinstance(resp, dict)
2039        return resp
2040
2041    async def fetch_content_by_tag_and_type(
2042        self, locale: str, tag: str, type: str, *, head: bool = False
2043    ) -> typedefs.JSONObject:
2044        resp = await self._request(
2045            _GET,
2046            f"Content/GetContentByTagAndType/{tag}/{type}/{locale}/",
2047            json={"head": head},
2048        )
2049        assert isinstance(resp, dict)
2050        return resp
2051
2052    async def search_content_with_text(
2053        self,
2054        locale: str,
2055        /,
2056        content_type: str,
2057        search_text: str,
2058        tag: str,
2059        *,
2060        page: int | None = None,
2061        source: str | None = None,
2062    ) -> typedefs.JSONObject:
2063        body: typedefs.JSONObject = {
2064            "locale": locale,
2065            "currentpage": page or 1,
2066            "ctype": content_type,
2067            "searchtxt": search_text,
2068            "searchtext": search_text,
2069            "tag": tag,
2070            "source": source,
2071        }
2072
2073        resp = await self._request(_GET, "Content/Search", params=body)
2074        assert isinstance(resp, dict)
2075        return resp
2076
2077    async def search_content_by_tag_and_type(
2078        self,
2079        locale: str,
2080        tag: str,
2081        type: str,
2082        *,
2083        page: int | None = None,
2084    ) -> typedefs.JSONObject:
2085        body: typedefs.JSONObject = {"currentpage": page or 1}
2086
2087        resp = await self._request(
2088            _GET,
2089            f"Content/SearchContentByTagAndType/{tag}/{type}/{locale}/",
2090            params=body,
2091        )
2092        assert isinstance(resp, dict)
2093        return resp
2094
2095    async def search_help_articles(
2096        self, text: str, size: str, /
2097    ) -> typedefs.JSONObject:
2098        resp = await self._request(_GET, f"Content/SearchHelpArticles/{text}/{size}/")
2099        assert isinstance(resp, dict)
2100        return resp
2101
2102    async def fetch_topics_page(
2103        self,
2104        category_filter: int,
2105        group: int,
2106        date_filter: int,
2107        sort: str | bytes,
2108        *,
2109        page: int | None = None,
2110        locales: collections.Iterable[str] | None = None,
2111        tag_filter: str | None = None,
2112    ) -> typedefs.JSONObject:
2113        params = {
2114            "locales": ",".join(locales) if locales is not None else "en",
2115        }
2116        if tag_filter:
2117            params["tagstring"] = tag_filter
2118
2119        resp = await self._request(
2120            _GET,
2121            f"Forum/GetTopicsPaged/{page or 0}/0/{group}/{sort!s}/{date_filter}/{category_filter}/",
2122            params=params,
2123        )
2124        assert isinstance(resp, dict)
2125        return resp
2126
2127    async def fetch_core_topics_page(
2128        self,
2129        category_filter: int,
2130        date_filter: int,
2131        sort: str | bytes,
2132        *,
2133        page: int | None = None,
2134        locales: collections.Iterable[str] | None = None,
2135    ) -> typedefs.JSONObject:
2136        resp = await self._request(
2137            _GET,
2138            f"Forum/GetCoreTopicsPaged/{page or 0}"
2139            f"/{sort!s}/{date_filter}/{category_filter}/?locales={','.join(locales) if locales else 'en'}",
2140        )
2141        assert isinstance(resp, dict)
2142        return resp
2143
2144    async def fetch_posts_threaded_page(
2145        self,
2146        parent_post: bool,
2147        page: int,
2148        page_size: int,
2149        parent_post_id: int,
2150        reply_size: int,
2151        root_thread_mode: bool,
2152        sort_mode: int,
2153        show_banned: str | None = None,
2154    ) -> typedefs.JSONObject:
2155        resp = await self._request(
2156            _GET,
2157            f"Forum/GetPostsThreadedPaged/{parent_post}/{page}/"
2158            f"{page_size}/{reply_size}/{parent_post_id}/{root_thread_mode}/{sort_mode}/",
2159            json={"showbanned": show_banned},
2160        )
2161        assert isinstance(resp, dict)
2162        return resp
2163
2164    async def fetch_posts_threaded_page_from_child(
2165        self,
2166        child_id: bool,
2167        page: int,
2168        page_size: int,
2169        reply_size: int,
2170        root_thread_mode: bool,
2171        sort_mode: int,
2172        show_banned: str | None = None,
2173    ) -> typedefs.JSONObject:
2174        resp = await self._request(
2175            _GET,
2176            f"Forum/GetPostsThreadedPagedFromChild/{child_id}/"
2177            f"{page}/{page_size}/{reply_size}/{root_thread_mode}/{sort_mode}/",
2178            json={"showbanned": show_banned},
2179        )
2180        assert isinstance(resp, dict)
2181        return resp
2182
2183    async def fetch_post_and_parent(
2184        self, child_id: int, /, *, show_banned: str | None = None
2185    ) -> typedefs.JSONObject:
2186        resp = await self._request(
2187            _GET,
2188            f"Forum/GetPostAndParent/{child_id}/",
2189            json={"showbanned": show_banned},
2190        )
2191        assert isinstance(resp, dict)
2192        return resp
2193
2194    async def fetch_posts_and_parent_awaiting(
2195        self, child_id: int, /, *, show_banned: str | None = None
2196    ) -> typedefs.JSONObject:
2197        resp = await self._request(
2198            _GET,
2199            f"Forum/GetPostAndParentAwaitingApproval/{child_id}/",
2200            json={"showbanned": show_banned},
2201        )
2202        assert isinstance(resp, dict)
2203        return resp
2204
2205    async def fetch_topic_for_content(self, content_id: int, /) -> int:
2206        resp = await self._request(_GET, f"Forum/GetTopicForContent/{content_id}/")
2207        assert isinstance(resp, int)
2208        return resp
2209
2210    async def fetch_forum_tag_suggestions(
2211        self, partial_tag: str, /
2212    ) -> typedefs.JSONObject:
2213        resp = await self._request(
2214            _GET,
2215            "Forum/GetForumTagSuggestions/",
2216            json={"partialtag": partial_tag},
2217        )
2218        assert isinstance(resp, dict)
2219        return resp
2220
2221    async def fetch_poll(self, topic_id: int, /) -> typedefs.JSONObject:
2222        resp = await self._request(_GET, f"Forum/Poll/{topic_id}/")
2223        assert isinstance(resp, dict)
2224        return resp
2225
2226    async def fetch_recruitment_thread_summaries(self) -> typedefs.JSONArray:
2227        resp = await self._request(_POST, "Forum/Recruit/Summaries/")
2228        assert isinstance(resp, list)
2229        return resp
2230
2231    async def fetch_recommended_groups(
2232        self,
2233        access_token: str,
2234        /,
2235        *,
2236        date_range: int = 0,
2237        group_type: enums.GroupType | int = enums.GroupType.CLAN,
2238    ) -> typedefs.JSONArray:
2239        resp = await self._request(
2240            _POST,
2241            f"GroupV2/Recommended/{int(group_type)}/{date_range}/",
2242            auth=access_token,
2243        )
2244        assert isinstance(resp, list)
2245        return resp
2246
2247    async def fetch_available_avatars(self) -> collections.Mapping[str, int]:
2248        resp = await self._request(_GET, "GroupV2/GetAvailableAvatars/")
2249        assert isinstance(resp, dict)
2250        return resp
2251
2252    async def fetch_user_clan_invite_setting(
2253        self,
2254        access_token: str,
2255        /,
2256        membership_type: enums.MembershipType | int,
2257    ) -> bool:
2258        resp = await self._request(
2259            _GET,
2260            f"GroupV2/GetUserClanInviteSetting/{int(membership_type)}/",
2261            auth=access_token,
2262        )
2263        assert isinstance(resp, bool)
2264        return resp
2265
2266    async def fetch_banned_group_members(
2267        self, access_token: str, group_id: int, /, *, page: int = 1
2268    ) -> typedefs.JSONObject:
2269        resp = await self._request(
2270            _GET,
2271            f"GroupV2/{group_id}/Banned/?currentpage={page}",
2272            auth=access_token,
2273        )
2274        assert isinstance(resp, dict)
2275        return resp
2276
2277    async def fetch_pending_group_memberships(
2278        self, access_token: str, group_id: int, /, *, current_page: int = 1
2279    ) -> typedefs.JSONObject:
2280        resp = await self._request(
2281            _GET,
2282            f"GroupV2/{group_id}/Members/Pending/?currentpage={current_page}",
2283            auth=access_token,
2284        )
2285        assert isinstance(resp, dict)
2286        return resp
2287
2288    async def fetch_invited_group_memberships(
2289        self, access_token: str, group_id: int, /, *, current_page: int = 1
2290    ) -> typedefs.JSONObject:
2291        resp = await self._request(
2292            _GET,
2293            f"GroupV2/{group_id}/Members/InvitedIndividuals/?currentpage={current_page}",
2294            auth=access_token,
2295        )
2296        assert isinstance(resp, dict)
2297        return resp
2298
2299    async def invite_member_to_group(
2300        self,
2301        access_token: str,
2302        /,
2303        group_id: int,
2304        membership_id: int,
2305        membership_type: enums.MembershipType | int,
2306        *,
2307        message: str | None = None,
2308    ) -> typedefs.JSONObject:
2309        resp = await self._request(
2310            _POST,
2311            f"GroupV2/{group_id}/Members/IndividualInvite/{int(membership_type)}/{membership_id}/",
2312            auth=access_token,
2313            json={"message": str(message)},
2314        )
2315        assert isinstance(resp, dict)
2316        return resp
2317
2318    async def cancel_group_member_invite(
2319        self,
2320        access_token: str,
2321        /,
2322        group_id: int,
2323        membership_id: int,
2324        membership_type: enums.MembershipType | int,
2325    ) -> typedefs.JSONObject:
2326        resp = await self._request(
2327            _POST,
2328            f"GroupV2/{group_id}/Members/IndividualInviteCancel/{int(membership_type)}/{membership_id}/",
2329            auth=access_token,
2330        )
2331        assert isinstance(resp, dict)
2332        return resp
2333
2334    async def fetch_historical_definition(self) -> typedefs.JSONObject:
2335        resp = await self._request(_GET, "Destiny2/Stats/Definition/")
2336        assert isinstance(resp, dict)
2337        return resp
2338
2339    async def fetch_historical_stats(
2340        self,
2341        character_id: int,
2342        membership_id: int,
2343        membership_type: enums.MembershipType | int,
2344        day_start: datetime.datetime,
2345        day_end: datetime.datetime,
2346        groups: collections.Sequence[enums.StatsGroupType | int],
2347        modes: collections.Sequence[enums.GameMode | int],
2348        *,
2349        period_type: enums.PeriodType = enums.PeriodType.ALL_TIME,
2350    ) -> typedefs.JSONObject:
2351        end, start = time.parse_date_range(day_end, day_start)
2352        resp = await self._request(
2353            _GET,
2354            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/",
2355            json={
2356                "dayend": end,
2357                "daystart": start,
2358                "groups": [str(int(group)) for group in groups],
2359                "modes": [str(int(mode)) for mode in modes],
2360                "periodType": int(period_type),
2361            },
2362        )
2363        assert isinstance(resp, dict)
2364        return resp
2365
2366    async def fetch_historical_stats_for_account(
2367        self,
2368        membership_id: int,
2369        membership_type: enums.MembershipType | int,
2370        groups: collections.Sequence[enums.StatsGroupType | int],
2371    ) -> typedefs.JSONObject:
2372        resp = await self._request(
2373            _GET,
2374            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Stats/",
2375            json={"groups": [str(int(group)) for group in groups]},
2376        )
2377        assert isinstance(resp, dict)
2378        return resp
2379
2380    async def fetch_aggregated_activity_stats(
2381        self,
2382        character_id: int,
2383        membership_id: int,
2384        membership_type: enums.MembershipType | int,
2385        /,
2386    ) -> typedefs.JSONObject:
2387        resp = await self._request(
2388            _GET,
2389            f"Destiny2/{int(membership_type)}/Account/{membership_id}/"
2390            f"Character/{character_id}/Stats/AggregateActivityStats/",
2391        )
2392        assert isinstance(resp, dict)
2393        return resp
2394
2395    async def equip_loadout(
2396        self,
2397        access_token: str,
2398        /,
2399        loadout_index: int,
2400        character_id: int,
2401        membership_type: enums.MembershipType | int,
2402    ) -> None:
2403        response = await self._request(
2404            _POST,
2405            "Destiny2/Actions/Loadouts/EquipLoadout/",
2406            json={
2407                "loadoutIndex": loadout_index,
2408                "characterId": character_id,
2409                "membership_type": int(membership_type),
2410            },
2411            auth=access_token,
2412        )
2413        assert isinstance(response, int)
2414
2415    async def snapshot_loadout(
2416        self,
2417        access_token: str,
2418        /,
2419        loadout_index: int,
2420        character_id: int,
2421        membership_type: enums.MembershipType | int,
2422        *,
2423        color_hash: int | None = None,
2424        icon_hash: int | None = None,
2425        name_hash: int | None = None,
2426    ) -> None:
2427        response = await self._request(
2428            _POST,
2429            "Destiny2/Actions/Loadouts/SnapshotLoadout/",
2430            auth=access_token,
2431            json={
2432                "colorHash": color_hash,
2433                "iconHash": icon_hash,
2434                "nameHash": name_hash,
2435                "loadoutIndex": loadout_index,
2436                "characterId": character_id,
2437                "membershipType": int(membership_type),
2438            },
2439        )
2440        assert isinstance(response, int)
2441
2442    async def update_loadout(
2443        self,
2444        access_token: str,
2445        /,
2446        loadout_index: int,
2447        character_id: int,
2448        membership_type: enums.MembershipType | int,
2449        *,
2450        color_hash: int | None = None,
2451        icon_hash: int | None = None,
2452        name_hash: int | None = None,
2453    ) -> None:
2454        response = await self._request(
2455            _POST,
2456            "Destiny2/Actions/Loadouts/UpdateLoadoutIdentifiers/",
2457            auth=access_token,
2458            json={
2459                "colorHash": color_hash,
2460                "iconHash": icon_hash,
2461                "nameHash": name_hash,
2462                "loadoutIndex": loadout_index,
2463                "characterId": character_id,
2464                "membershipType": int(membership_type),
2465            },
2466        )
2467        assert isinstance(response, int)
2468
2469    async def clear_loadout(
2470        self,
2471        access_token: str,
2472        /,
2473        loadout_index: int,
2474        character_id: int,
2475        membership_type: enums.MembershipType | int,
2476    ) -> None:
2477        response = await self._request(
2478            _POST,
2479            "Destiny2/Actions/Loadouts/ClearLoadout/",
2480            json={
2481                "loadoutIndex": loadout_index,
2482                "characterId": character_id,
2483                "membership_type": int(membership_type),
2484            },
2485            auth=access_token,
2486        )
2487        assert isinstance(response, int)
2488
2489    async def force_drops_repair(self, access_token: str, /) -> bool:
2490        response = await self._request(
2491            _POST, "Tokens/Partner/ForceDropsRepair/", auth=access_token
2492        )
2493        assert isinstance(response, bool)
2494        return response
2495
2496    async def claim_partner_offer(
2497        self,
2498        access_token: str,
2499        /,
2500        *,
2501        offer_id: str,
2502        bungie_membership_id: int,
2503        transaction_id: str,
2504    ) -> bool:
2505        response = await self._request(
2506            _POST,
2507            "Tokens/Partner/ClaimOffer/",
2508            json={
2509                "PartnerOfferId": offer_id,
2510                "BungieNetMembershipId": bungie_membership_id,
2511                "TransactionId": transaction_id,
2512            },
2513            auth=access_token,
2514        )
2515        assert isinstance(response, bool)
2516        return response
2517
2518    async def fetch_bungie_rewards_for_user(
2519        self, access_token: str, /, membership_id: int
2520    ) -> typedefs.JSONObject:
2521        response = await self._request(
2522            _GET,
2523            f"Tokens/Rewards/GetRewardsForUser/{membership_id}/",
2524            auth=access_token,
2525        )
2526        assert isinstance(response, dict)
2527        return response
2528
2529    async def fetch_bungie_rewards_for_platform(
2530        self,
2531        access_token: str,
2532        /,
2533        membership_id: int,
2534        membership_type: enums.MembershipType | int,
2535    ) -> typedefs.JSONObject:
2536        response = await self._request(
2537            _GET,
2538            f"Tokens/Rewards/GetRewardsForPlatformUser/{membership_id}/{int(membership_type)}",
2539            auth=access_token,
2540        )
2541        assert isinstance(response, dict)
2542        return response
2543
2544    async def fetch_bungie_rewards(self) -> typedefs.JSONObject:
2545        response = await self._request(_GET, "Tokens/Rewards/BungieRewards/")
2546        assert isinstance(response, dict)
2547        return response
2548
2549    async def fetch_fireteam_listing(self, listing_id: int) -> typedefs.JSONObject:
2550        response = await self._request(_GET, f"FireteamFinder/Listing/{listing_id}/")
2551        assert isinstance(response, dict)
2552        return response

A single process REST client implementation.

This client is designed to only make HTTP requests and return raw JSON objects.

Example
import aiobungie

client = aiobungie.RESTClient("TOKEN")
async with client:
    response = await client.fetch_clan_members(4389205)
    for member in response['results']:
        print(member['destinyUserInfo'])
Parameters
  • token (str): A valid application token from Bungie's developer portal.
Other Parameters
  • client_secret (str | None): An optional application client secret, This is only needed if you're fetching OAuth2 tokens with this client.
  • client_id (int | None): An optional application client id, This is only needed if you're fetching OAuth2 tokens with this client.
  • settings (aiobungie.builders.Settings | None): The client settings to use, if None the default will be used.
  • owned_client (bool):
    • If set to True, this client will use the provided client_session parameter instead,
    • If set to True and client_session is None, ValueError will be raised.
    • If set to False, aiobungie will initialize a new client session for you.
  • client_session (aiohttp.ClientSession | None): If provided, this client session will be used to make all the HTTP requests. The owned_client must be set to True for this to work.
  • max_retries (int): The max retries number to retry if the request hit a 5xx status code.
  • debug (bool | str): Whether to enable logging responses or not.
Logging Levels
  • False: This will disable logging.
  • True: This will set the level to DEBUG and enable logging minimal information.
  • "TRACE" | aiobungie.TRACE: This will log the response headers along with the minimal information.
RESTClient( token: 'str', /, *, client_secret: 'str | None' = None, client_id: 'int | None' = None, settings: 'builders.Settings | None' = None, owned_client: 'bool' = True, client_session: 'aiohttp.ClientSession | None' = None, dumps: 'typedefs.Dumps' = <function dumps>, loads: 'typedefs.Loads' = <function loads>, max_retries: 'int' = 4, debug: "typing.Literal['TRACE'] | bool | int" = False)
496    def __init__(
497        self,
498        token: str,
499        /,
500        *,
501        client_secret: str | None = None,
502        client_id: int | None = None,
503        settings: builders.Settings | None = None,
504        owned_client: bool = True,
505        client_session: aiohttp.ClientSession | None = None,
506        dumps: typedefs.Dumps = helpers.dumps,
507        loads: typedefs.Loads = helpers.loads,
508        max_retries: int = 4,
509        debug: typing.Literal["TRACE"] | bool | int = False,
510    ) -> None:
511        if owned_client is False and client_session is None:
512            raise ValueError(
513                "Expected an owned client session, but got `None`, Cannot have `owned_client` set to `False` and `client_session` to `None`"
514            )
515
516        self._settings = settings or builders.Settings()
517        self._session = client_session
518        self._owned_client = owned_client
519        self._lock: asyncio.Lock | None = None
520        self._client_secret = client_secret
521        self._client_id = client_id
522        self._token: str = token
523        self._max_retries = max_retries
524        self._dumps = dumps
525        self._loads = loads
526        self._metadata: collections.MutableMapping[typing.Any, typing.Any] = {}
527        self.with_debug(debug)
client_id: 'int | None'
529    @property
530    def client_id(self) -> int | None:
531        return self._client_id

Return the client id of this REST client if provided, Otherwise None.

metadata: 'collections.MutableMapping[typing.Any, typing.Any]'
533    @property
534    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
535        return self._metadata

A mutable mapping storage for the user's needs.

This mapping is useful for storing any kind of data that the user may need to access later from a different process.

Example
import aiobungie

client = aiobungie.RESTClient(…)

async with client:
    # Fetch auth tokens and store them
    client.metadata["tokens"] = await client.fetch_access_token("code")

# Some other time.
async with client:
    # Retrieve the tokens
    tokens: aiobungie.OAuth2Response = client.metadata["tokens"]

    # Use them to fetch your user.
    user = await client.fetch_current_user_memberships(tokens.access_token)
is_alive: 'bool'
537    @property
538    def is_alive(self) -> bool:
539        return self._session is not None

Returns True if the REST client is alive and False otherwise.

settings: 'builders.Settings'
541    @property
542    def settings(self) -> builders.Settings:
543        return self._settings

Internal client settings used within the HTTP client session.

async def close(self) -> 'None':
545    async def close(self) -> None:
546        if self._session is None:
547            raise RuntimeError("REST client is not running.")
548
549        if self._owned_client:
550            await self._session.close()
551            self._session = None

Close this REST client session if it was acquired.

This method is automatically called when using async with contextmanager.

Raises
  • RuntimeError: If the client is already closed.
def open(self) -> 'None':
553    def open(self) -> None:
554        """Open a new client session. This is called internally with contextmanager usage."""
555        if self.is_alive and self._owned_client:
556            raise RuntimeError("Cannot open REST client when it's already open.")
557
558        if self._owned_client:
559            self._session = aiohttp.ClientSession(
560                connector=aiohttp.TCPConnector(
561                    use_dns_cache=self._settings.use_dns_cache,
562                    ttl_dns_cache=self._settings.ttl_dns_cache,
563                    ssl_context=self._settings.ssl_context,
564                    ssl=self._settings.ssl,
565                ),
566                connector_owner=True,
567                raise_for_status=False,
568                timeout=self._settings.http_timeout,
569                trust_env=self._settings.trust_env,
570                headers=self._settings.headers,
571            )

Open a new client session. This is called internally with contextmanager usage.

@typing.final
async def static_request( self, method: '_HTTP_METHOD', path: 'str', *, auth: 'str | None' = None, json: 'collections.Mapping[str, typing.Any] | None' = None, params: 'collections.Mapping[str, typing.Any] | None' = None) -> 'typedefs.JSONIsh':
573    @typing.final
574    async def static_request(
575        self,
576        method: _HTTP_METHOD,
577        path: str,
578        *,
579        auth: str | None = None,
580        json: collections.Mapping[str, typing.Any] | None = None,
581        params: collections.Mapping[str, typing.Any] | None = None,
582    ) -> typedefs.JSONIsh:
583        return await self._request(method, path, auth=auth, json=json, params=params)

Perform an HTTP request given a valid Bungie endpoint.

This method allows you to freely perform HTTP requests to Bungie's API. It provides authentication support, JSON bodies, URL parameters and out of the box exception handling.

This method is useful for testing routes by yourself. or even calling routes that aiobungie doesn't support yet.

Parameters
  • method (str): The request method, This may be GET, POST, PUT, etc.
  • path (str): The Bungie endpoint or path. A path must look something like this Destiny2/3/Profile/46111239123/...
Other Parameters
  • auth (str | None): An optional bearer token for methods that requires OAuth2 Authorization header.
  • json (MutableMapping[str, typing.Any] | None): An optional JSON mapping to include in the request.
  • params (MutableMapping[str, typing.Any] | None): An optional URL query parameters mapping to include in the request.
Returns
  • aiobungie.typedefs.JSONIsh: The response payload.
@typing.final
def build_oauth2_url(self, client_id: 'int | None' = None) -> 'builders.OAuthURL | None':
591    @typing.final
592    def build_oauth2_url(
593        self, client_id: int | None = None
594    ) -> builders.OAuthURL | None:
595        client_id = client_id or self._client_id
596        if client_id is None:
597            return None
598
599        return builders.OAuthURL(client_id=client_id)

Construct a new OAuthURL url object.

You can get the complete string representation of the url by calling .compile() on it.

Parameters
  • client_id (int | None): An optional client id to provide, If left None it will roll back to the id passed to the RESTClient, If both is None this method will return None.
Returns
async def fetch_oauth2_tokens(self, code: 'str', /) -> 'builders.OAuth2Response':
822    async def fetch_oauth2_tokens(self, code: str, /) -> builders.OAuth2Response:
823        data = {
824            "grant_type": "authorization_code",
825            "code": code,
826            "client_id": self._client_id,
827            "client_secret": self._client_secret,
828        }
829
830        response = await self._request(_POST, "", data=data, oauth2=True)
831        assert isinstance(response, dict)
832        return builders.OAuth2Response.build_response(response)

Makes a POST request and fetch the OAuth2 access_token and refresh token.

Parameters
  • code (str): The Authorization code received from the authorization endpoint found in the URL parameters.
Returns
Raises
async def refresh_access_token(self, refresh_token: 'str', /) -> 'builders.OAuth2Response':
834    async def refresh_access_token(
835        self, refresh_token: str, /
836    ) -> builders.OAuth2Response:
837        data = {
838            "grant_type": "refresh_token",
839            "refresh_token": refresh_token,
840            "client_id": self._client_id,
841            "client_secret": self._client_secret,
842        }
843
844        response = await self._request(_POST, "", data=data, oauth2=True)
845        assert isinstance(response, dict)
846        return builders.OAuth2Response.build_response(response)

Refresh OAuth2 access token given its refresh token.

Parameters
  • refresh_token (str): The refresh token.
Returns
async def fetch_bungie_user(self, id: 'int') -> 'typedefs.JSONObject':
848    async def fetch_bungie_user(self, id: int) -> typedefs.JSONObject:
849        resp = await self._request(_GET, f"User/GetBungieNetUserById/{id}/")
850        assert isinstance(resp, dict)
851        return resp

Fetch a Bungie user by their id.

Parameters
  • id (int): The user id.
Returns
Raises
async def fetch_user_themes(self) -> 'typedefs.JSONArray':
853    async def fetch_user_themes(self) -> typedefs.JSONArray:
854        resp = await self._request(_GET, "User/GetAvailableThemes/")
855        assert isinstance(resp, list)
856        return resp

Fetch all available user themes.

Returns
async def fetch_membership_from_id( self, id: 'int', type: 'enums.MembershipType | int' = <MembershipType.NONE: 0>, /) -> 'typedefs.JSONObject':
858    async def fetch_membership_from_id(
859        self,
860        id: int,
861        type: enums.MembershipType | int = enums.MembershipType.NONE,
862        /,
863    ) -> typedefs.JSONObject:
864        resp = await self._request(_GET, f"User/GetMembershipsById/{id}/{int(type)}")
865        assert isinstance(resp, dict)
866        return resp

Fetch Bungie user's memberships from their id.

Parameters
Returns
Raises
async def fetch_membership( self, name: 'str', code: 'int', type: 'enums.MembershipType | int' = <MembershipType.ALL: -1>, /) -> 'typedefs.JSONArray':
868    async def fetch_membership(
869        self,
870        name: str,
871        code: int,
872        type: enums.MembershipType | int = enums.MembershipType.ALL,
873        /,
874    ) -> typedefs.JSONArray:
875        resp = await self._request(
876            _POST,
877            f"Destiny2/SearchDestinyPlayerByBungieName/{int(type)}",
878            json={"displayName": name, "displayNameCode": code},
879        )
880        assert isinstance(resp, list)
881        return resp

Fetch a Destiny 2 Player.

Parameters
  • name (str): The unique Bungie player name.
  • code (int): The unique Bungie display name code.
  • type (aiobungie.aiobungie.MembershipType | int): The player's membership type, e,g. XBOX, STEAM, PSN
Returns
Raises
async def fetch_sanitized_membership(self, membership_id: 'int', /) -> 'typedefs.JSONObject':
883    async def fetch_sanitized_membership(
884        self, membership_id: int, /
885    ) -> typedefs.JSONObject:
886        response = await self._request(
887            _GET, f"User/GetSanitizedPlatformDisplayNames/{membership_id}/"
888        )
889        assert isinstance(response, dict)
890        return response

Fetch a list of all display names linked to membership_id, Which is profanity filtered.

Parameters
  • membership_id (int): The membership ID to fetch
Returns
async def search_users(self, name: 'str', /) -> 'typedefs.JSONObject':
892    async def search_users(self, name: str, /) -> typedefs.JSONObject:
893        resp = await self._request(
894            _POST,
895            "User/Search/GlobalName/0",
896            json={"displayNamePrefix": name},
897        )
898        assert isinstance(resp, dict)
899        return resp

Search for users by their global name and return all users who share this name.

Parameters
  • name (str): The user name.
Returns
Raises
async def fetch_clan_from_id( self, id: 'int', /, access_token: 'str | None' = None) -> 'typedefs.JSONObject':
901    async def fetch_clan_from_id(
902        self, id: int, /, access_token: str | None = None
903    ) -> typedefs.JSONObject:
904        resp = await self._request(_GET, f"GroupV2/{id}", auth=access_token)
905        assert isinstance(resp, dict)
906        return resp

Fetch a Bungie Clan by its id.

Parameters
  • id (int): The clan id.
Other Parameters
  • access_token (str | None): An optional access token to make the request with.

    If the token was bound to a member of the clan, This field aiobungie.crates.Clan.current_user_membership will be available and will return the membership of the user who made this request.

Returns
Raises
async def fetch_clan( self, name: 'str', /, access_token: 'str | None' = None, *, type: 'enums.GroupType | int' = <GroupType.CLAN: 1>) -> 'typedefs.JSONObject':
908    async def fetch_clan(
909        self,
910        name: str,
911        /,
912        access_token: str | None = None,
913        *,
914        type: enums.GroupType | int = enums.GroupType.CLAN,
915    ) -> typedefs.JSONObject:
916        resp = await self._request(
917            _GET, f"GroupV2/Name/{name}/{int(type)}", auth=access_token
918        )
919        assert isinstance(resp, dict)
920        return resp

Fetch a Clan by its name. This method will return the first clan found with given name name.

Parameters
  • name (str): The clan name.
Other Parameters
Returns
Raises
async def search_group( self, name: 'str', group_type: 'enums.GroupType | int' = <GroupType.CLAN: 1>, *, creation_date: 'clans.GroupDate | int' = 0, sort_by: 'int | None' = None, group_member_count_filter: 'typing.Literal[0, 1, 2, 3] | None' = None, locale_filter: 'str | None' = None, tag_text: 'str | None' = None, items_per_page: 'int | None' = None, current_page: 'int | None' = None, request_token: 'str | None' = None) -> 'typedefs.JSONObject':
922    async def search_group(
923        self,
924        name: str,
925        group_type: enums.GroupType | int = enums.GroupType.CLAN,
926        *,
927        creation_date: clans.GroupDate | int = 0,
928        sort_by: int | None = None,
929        group_member_count_filter: typing.Literal[0, 1, 2, 3] | None = None,
930        locale_filter: str | None = None,
931        tag_text: str | None = None,
932        items_per_page: int | None = None,
933        current_page: int | None = None,
934        request_token: str | None = None,
935    ) -> typedefs.JSONObject:
936        payload: collections.MutableMapping[str, typing.Any] = {"name": name}
937
938        # as the official documentation says, you're not allowed to use those fields
939        # on a clan search. it is safe to send the request with them being `null` but not filled with a value.
940        if (
941            group_type == enums.GroupType.CLAN
942            and group_member_count_filter is not None
943            and locale_filter
944            and tag_text
945        ):
946            raise ValueError(
947                "If you're searching for clans, (group_member_count_filter, locale_filter, tag_text) must be None."
948            )
949
950        payload["groupType"] = int(group_type)
951        payload["creationDate"] = int(creation_date)
952        payload["sortBy"] = sort_by
953        payload["groupMemberCount"] = group_member_count_filter
954        payload["locale"] = locale_filter
955        payload["tagText"] = tag_text
956        payload["itemsPerPage"] = items_per_page
957        payload["currentPage"] = current_page
958        payload["requestToken"] = request_token
959        payload["requestContinuationToken"] = request_token
960
961        resp = await self._request(_POST, "GroupV2/Search/", json=payload)
962        assert isinstance(resp, dict)
963        return resp

Search for groups.

If the group type is set to CLAN, then parameters group_member_count_filter, locale_filter and tag_text must be None, otherwise ValueError will be raised.

Parameters
  • name (str): The group name.
  • group_type (aiobungie.GroupType | int): The group type that's being searched for.
Other Parameters
  • creation_date (aiobungie.GroupDate | int): The creation date of the group. Defaults to 0 which is all time.
  • sort_by (int | None): ...
  • group_member_count_filter (int | None): ...
  • locale_filter (str | None): ...
  • tag_text (str | None): ...
  • items_per_page (int | None): ...
  • current_page (int | None): ...
  • request_token (str | None): ...
Returns
Raises
  • ValueError: If the group type is aiobungie.GroupType.CLAN and group_member_count_filter, locale_filter and tag_text are not None.
async def fetch_clan_admins(self, clan_id: 'int', /) -> 'typedefs.JSONObject':
965    async def fetch_clan_admins(self, clan_id: int, /) -> typedefs.JSONObject:
966        resp = await self._request(_GET, f"GroupV2/{clan_id}/AdminsAndFounder/")
967        assert isinstance(resp, dict)
968        return resp

Fetch the admins and founder members of the clan.

Parameters
  • clan_id (int): The clan id.
Returns
Raises
async def fetch_clan_conversations(self, clan_id: 'int', /) -> 'typedefs.JSONArray':
970    async def fetch_clan_conversations(self, clan_id: int, /) -> typedefs.JSONArray:
971        resp = await self._request(_GET, f"GroupV2/{clan_id}/OptionalConversations/")
972        assert isinstance(resp, list)
973        return resp

Fetch a clan's conversations.

Parameters
  • clan_id (int): The clan's id.
Returns
async def fetch_application(self, appid: 'int', /) -> 'typedefs.JSONObject':
975    async def fetch_application(self, appid: int, /) -> typedefs.JSONObject:
976        resp = await self._request(_GET, f"App/Application/{appid}")
977        assert isinstance(resp, dict)
978        return resp

Fetch a Bungie Application.

Parameters
  • appid (int): The application id.
Returns
async def fetch_character( self, member_id: 'int', membership_type: 'enums.MembershipType | int', character_id: 'int', components: 'collections.Sequence[enums.ComponentType]', auth: 'str | None' = None) -> 'typedefs.JSONObject':
980    async def fetch_character(
981        self,
982        member_id: int,
983        membership_type: enums.MembershipType | int,
984        character_id: int,
985        components: collections.Sequence[enums.ComponentType],
986        auth: str | None = None,
987    ) -> typedefs.JSONObject:
988        collector = _collect_components(components)
989        response = await self._request(
990            _GET,
991            f"Destiny2/{int(membership_type)}/Profile/{member_id}/"
992            f"Character/{character_id}/?components={collector}",
993            auth=auth,
994        )
995        assert isinstance(response, dict)
996        return response

Fetch a Destiny 2 player's characters.

Parameters
Other Parameters
  • auth (str | None): A bearer access_token to make the request with. This is optional and limited to components that only requires an Authorization token.
Returns
Raises
async def fetch_activities( self, member_id: 'int', character_id: 'int', mode: 'enums.GameMode | int', membership_type: 'enums.MembershipType | int' = <MembershipType.ALL: -1>, *, page: 'int' = 0, limit: 'int' = 1) -> 'typedefs.JSONObject':
 998    async def fetch_activities(
 999        self,
1000        member_id: int,
1001        character_id: int,
1002        mode: enums.GameMode | int,
1003        membership_type: enums.MembershipType | int = enums.MembershipType.ALL,
1004        *,
1005        page: int = 0,
1006        limit: int = 1,
1007    ) -> typedefs.JSONObject:
1008        resp = await self._request(
1009            _GET,
1010            f"Destiny2/{int(membership_type)}/Account/"
1011            f"{member_id}/Character/{character_id}/Stats/Activities"
1012            f"/?mode={int(mode)}&count={limit}&page={page}",
1013        )
1014        assert isinstance(resp, dict)
1015        return resp

Fetch a Destiny 2 activity for the specified user id and character.

Parameters
Other Parameters
  • page (int): The page number. Default to 1
  • limit (int): Limit the returned result. Default to 1
Returns
Raises
async def fetch_vendor_sales(self) -> 'typedefs.JSONObject':
1017    async def fetch_vendor_sales(self) -> typedefs.JSONObject:
1018        resp = await self._request(
1019            _GET,
1020            f"Destiny2/Vendors/?components={int(enums.ComponentType.VENDOR_SALES)}",
1021        )
1022        assert isinstance(resp, dict)
1023        return resp
async def fetch_profile( self, membership_id: 'int', type: 'enums.MembershipType | int', components: 'collections.Sequence[enums.ComponentType]', auth: 'str | None' = None) -> 'typedefs.JSONObject':
1025    async def fetch_profile(
1026        self,
1027        membership_id: int,
1028        type: enums.MembershipType | int,
1029        components: collections.Sequence[enums.ComponentType],
1030        auth: str | None = None,
1031    ) -> typedefs.JSONObject:
1032        collector = _collect_components(components)
1033        response = await self._request(
1034            _GET,
1035            f"Destiny2/{int(type)}/Profile/{membership_id}/?components={collector}",
1036            auth=auth,
1037        )
1038        assert isinstance(response, dict)
1039        return response

Fetch a bungie profile.

Parameters
Other Parameters
  • auth (str | None): A bearer access_token to make the request with. This is optional and limited to components that only requires an Authorization token.
Returns
Raises
async def fetch_entity(self, type: 'str', hash: 'int') -> 'typedefs.JSONObject':
1041    async def fetch_entity(self, type: str, hash: int) -> typedefs.JSONObject:
1042        response = await self._request(_GET, route=f"Destiny2/Manifest/{type}/{hash}")
1043        assert isinstance(response, dict)
1044        return response

Fetch a Destiny definition item given its type and hash.

Parameters
  • type (str): Entity's type definition.
  • hash (int): Entity's hash.
Returns
async def fetch_inventory_item(self, hash: 'int', /) -> 'typedefs.JSONObject':
1046    async def fetch_inventory_item(self, hash: int, /) -> typedefs.JSONObject:
1047        resp = await self.fetch_entity("DestinyInventoryItemDefinition", hash)
1048        assert isinstance(resp, dict)
1049        return resp

Fetch a Destiny inventory item entity given a its hash.

Parameters
  • hash (int): Entity's hash.
Returns
async def fetch_objective_entity(self, hash: 'int', /) -> 'typedefs.JSONObject':
1051    async def fetch_objective_entity(self, hash: int, /) -> typedefs.JSONObject:
1052        resp = await self.fetch_entity("DestinyObjectiveDefinition", hash)
1053        assert isinstance(resp, dict)
1054        return resp

Fetch a Destiny objective entity given a its hash.

Parameters
  • hash (int): objective's hash.
Returns
async def fetch_groups_for_member( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, filter: 'int' = 0, group_type: 'enums.GroupType | int' = <GroupType.CLAN: 1>) -> 'typedefs.JSONObject':
1056    async def fetch_groups_for_member(
1057        self,
1058        member_id: int,
1059        member_type: enums.MembershipType | int,
1060        /,
1061        *,
1062        filter: int = 0,
1063        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1064    ) -> typedefs.JSONObject:
1065        resp = await self._request(
1066            _GET,
1067            f"GroupV2/User/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1068        )
1069        assert isinstance(resp, dict)
1070        return resp

Fetch the information about the groups for a member.

Parameters
Other Parameters
Returns
async def fetch_potential_groups_for_member( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, filter: 'int' = 0, group_type: 'enums.GroupType | int' = <GroupType.CLAN: 1>) -> 'typedefs.JSONObject':
1072    async def fetch_potential_groups_for_member(
1073        self,
1074        member_id: int,
1075        member_type: enums.MembershipType | int,
1076        /,
1077        *,
1078        filter: int = 0,
1079        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1080    ) -> typedefs.JSONObject:
1081        resp = await self._request(
1082            _GET,
1083            f"GroupV2/User/Potential/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1084        )
1085        assert isinstance(resp, dict)
1086        return resp

Get information about the groups that a given member has applied to or been invited to.

Parameters
Other Parameters
Returns
async def fetch_clan_members( self, clan_id: 'int', /, *, name: 'str | None' = None, type: 'enums.MembershipType | int' = <MembershipType.NONE: 0>) -> 'typedefs.JSONObject':
1088    async def fetch_clan_members(
1089        self,
1090        clan_id: int,
1091        /,
1092        *,
1093        name: str | None = None,
1094        type: enums.MembershipType | int = enums.MembershipType.NONE,
1095    ) -> typedefs.JSONObject:
1096        resp = await self._request(
1097            _GET,
1098            f"/GroupV2/{clan_id}/Members/?memberType={int(type)}&nameSearch={name if name else ''}&currentpage=1",
1099        )
1100        assert isinstance(resp, dict)
1101        return resp

Fetch all Bungie Clan members.

Parameters
  • clan_id (int): The clans id
Other Parameters
Returns
Raises
async def fetch_hardlinked_credentials( self, credential: 'int', type: 'enums.CredentialType | int' = <CredentialType.STEAMID: 12>, /) -> 'typedefs.JSONObject':
1103    async def fetch_hardlinked_credentials(
1104        self,
1105        credential: int,
1106        type: enums.CredentialType | int = enums.CredentialType.STEAMID,
1107        /,
1108    ) -> typedefs.JSONObject:
1109        resp = await self._request(
1110            _GET,
1111            f"User/GetMembershipFromHardLinkedCredential/{int(type)}/{credential}/",
1112        )
1113        assert isinstance(resp, dict)
1114        return resp

Gets any hard linked membership given a credential.

Only works for credentials that are public just aiobungie.CredentialType.STEAMID right now. Cross Save aware.

Parameters
  • credential (int): A valid SteamID64
  • type (aiobungie.aiobungie.CredentialType | int): The credential type. This must not be changed Since its only credential that works "currently"
Returns
async def fetch_user_credentials( self, access_token: 'str', membership_id: 'int', /) -> 'typedefs.JSONArray':
1116    async def fetch_user_credentials(
1117        self, access_token: str, membership_id: int, /
1118    ) -> typedefs.JSONArray:
1119        resp = await self._request(
1120            _GET,
1121            f"User/GetCredentialTypesForTargetAccount/{membership_id}",
1122            auth=access_token,
1123        )
1124        assert isinstance(resp, list)
1125        return resp

Fetch an array of credential types attached to the requested account.

This method require OAuth2 Bearer access token.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • membership_id (int): The id of the membership to return.
Returns
Raises
async def insert_socket_plug( self, action_token: 'str', /, instance_id: 'int', plug: 'builders.PlugSocketBuilder | collections.Mapping[str, int]', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
1127    async def insert_socket_plug(
1128        self,
1129        action_token: str,
1130        /,
1131        instance_id: int,
1132        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1133        character_id: int,
1134        membership_type: enums.MembershipType | int,
1135    ) -> typedefs.JSONObject:
1136        if isinstance(plug, builders.PlugSocketBuilder):
1137            plug = plug.collect()
1138
1139        body = {
1140            "actionToken": action_token,
1141            "itemInstanceId": instance_id,
1142            "plug": plug,
1143            "characterId": character_id,
1144            "membershipType": int(membership_type),
1145        }
1146        resp = await self._request(
1147            _POST, "Destiny2/Actions/Items/InsertSocketPlug", json=body
1148        )
1149        assert isinstance(resp, dict)
1150        return resp

Insert a plug into a socketed item.

OAuth2: AdvancedWriteActions scope is required

Parameters
  • action_token (str): Action token provided by the AwaGetActionToken API call.
  • instance_id (int): The item instance id that's plug inserted.
  • plug (aiobungie.builders.PlugSocketBuilder | Mapping[str, int]): Either a PlugSocketBuilder object or a raw dict contains key, value for the plug entries.
Example
plug = (
    aiobungie.PlugSocketBuilder()
    .set_socket_array(0)
    .set_socket_index(0)
    .set_plug_item(3023847)
    .collect()
)
await insert_socket_plug_free(..., plug=plug)

character_id : int The character's id. membership_type : aiobungie.aiobungie.MembershipType | int The membership type.

Returns
Raises
async def insert_socket_plug_free( self, access_token: 'str', /, instance_id: 'int', plug: 'builders.PlugSocketBuilder | collections.Mapping[str, int]', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
1152    async def insert_socket_plug_free(
1153        self,
1154        access_token: str,
1155        /,
1156        instance_id: int,
1157        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1158        character_id: int,
1159        membership_type: enums.MembershipType | int,
1160    ) -> typedefs.JSONObject:
1161        if isinstance(plug, builders.PlugSocketBuilder):
1162            plug = plug.collect()
1163
1164        body = {
1165            "itemInstanceId": instance_id,
1166            "plug": plug,
1167            "characterId": character_id,
1168            "membershipType": int(membership_type),
1169        }
1170        resp = await self._request(
1171            _POST,
1172            "Destiny2/Actions/Items/InsertSocketPlugFree",
1173            json=body,
1174            auth=access_token,
1175        )
1176        assert isinstance(resp, dict)
1177        return resp

Insert a plug into a socketed item. This doesn't require an Action token.

OAuth2: MoveEquipDestinyItems scope is required

Parameters
  • instance_id (int): The item instance id that's plug inserted.
  • plug (aiobungie.builders.PlugSocketBuilder | Mapping[str, int]): Either a PlugSocketBuilder object or a raw dict contains key, value for the plug entries.
Example
plug = (
    aiobungie.PlugSocketBuilder()
    .set_socket_array(0)
    .set_socket_index(0)
    .set_plug_item(3023847)
    .collect()
)
await insert_socket_plug_free(..., plug=plug)

character_id : int The character's id. membership_type : aiobungie.aiobungie.MembershipType | int The membership type.

Returns
Raises
@helpers.unstable
async def set_item_lock_state( self, access_token: 'str', state: 'bool', /, item_id: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'int':
1179    @helpers.unstable
1180    async def set_item_lock_state(
1181        self,
1182        access_token: str,
1183        state: bool,
1184        /,
1185        item_id: int,
1186        character_id: int,
1187        membership_type: enums.MembershipType | int,
1188    ) -> int:
1189        body = {
1190            "state": state,
1191            "itemId": item_id,
1192            "characterId": character_id,
1193            "membershipType": int(membership_type),
1194        }
1195        response = await self._request(
1196            _POST,
1197            "Destiny2/Actions/Items/SetLockState",
1198            json=body,
1199            auth=access_token,
1200        )
1201        assert isinstance(response, int)
1202        return response

Set the Lock State for an instanced item.

OAuth2: MoveEquipDestinyItems scope is required

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • state (bool): If True, The item will be locked, If False, The item will be unlocked.
  • item_id (int): The item id.
  • character_id (int): The character id.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The membership type for the associated account.
Returns
  • int: An integer represents whether the request was successful or failed.
Raises
async def set_quest_track_state( self, access_token: 'str', state: 'bool', /, item_id: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'int':
1204    async def set_quest_track_state(
1205        self,
1206        access_token: str,
1207        state: bool,
1208        /,
1209        item_id: int,
1210        character_id: int,
1211        membership_type: enums.MembershipType | int,
1212    ) -> int:
1213        body = {
1214            "state": state,
1215            "itemId": item_id,
1216            "characterId": character_id,
1217            "membership_type": int(membership_type),
1218        }
1219        response = await self._request(
1220            _POST,
1221            "Destiny2/Actions/Items/SetTrackedState",
1222            json=body,
1223            auth=access_token,
1224        )
1225        assert isinstance(response, int)
1226        return response

Set the Tracking State for an instanced Quest or Bounty.

OAuth2: MoveEquipDestinyItems scope is required

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • state (bool): If True, The item will be locked, If False, The item will be unlocked.
  • item_id (int): The item id.
  • character_id (int): The character id.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The membership type for the associated account.
Returns
  • int: An integer represents whether the request was successful or failed.
Raises
async def fetch_manifest_path(self) -> 'typedefs.JSONObject':
1228    async def fetch_manifest_path(self) -> typedefs.JSONObject:
1229        path = await self._request(_GET, "Destiny2/Manifest")
1230        assert isinstance(path, dict)
1231        return path

Fetch the manifest JSON paths.

Returns
  • typedefs.JSONObject: The manifest JSON paths.
async def read_manifest_bytes(self, language: '_ALLOWED_LANGS' = 'en', /) -> 'bytes':
1233    async def read_manifest_bytes(self, language: _ALLOWED_LANGS = "en", /) -> bytes:
1234        _ensure_manifest_language(language)
1235
1236        content = await self.fetch_manifest_path()
1237        resp = await self._request(
1238            _GET,
1239            content["mobileWorldContentPaths"][language],
1240            unwrap_bytes=True,
1241            base=True,
1242        )
1243        assert isinstance(resp, bytes)
1244        return resp

Read raw manifest SQLite database bytes response.

This method can be used to write the bytes to zipped file and then extract it to get the manifest content.

Parameters
  • language (str): The manifest database language bytes to get.
Returns
  • bytes: The bytes to read and write the manifest database.
async def download_sqlite_manifest( self, language: '_ALLOWED_LANGS' = 'en', name: 'str' = 'manifest', path: 'pathlib.Path | str' = '.', *, force: 'bool' = False, executor: 'concurrent.futures.Executor | None' = None) -> 'pathlib.Path':
1246    async def download_sqlite_manifest(
1247        self,
1248        language: _ALLOWED_LANGS = "en",
1249        name: str = "manifest",
1250        path: pathlib.Path | str = ".",
1251        *,
1252        force: bool = False,
1253        executor: concurrent.futures.Executor | None = None,
1254    ) -> pathlib.Path:
1255        complete_path = _get_path(name, path, sql=True)
1256
1257        if complete_path.exists():
1258            if force:
1259                _LOGGER.info(
1260                    f"Found manifest in {complete_path!s}. Forcing to Re-Download."
1261                )
1262                complete_path.unlink(missing_ok=True)
1263
1264                return await self.download_sqlite_manifest(
1265                    language, name, path, force=force
1266                )
1267
1268            else:
1269                raise FileExistsError(
1270                    "Manifest file already exists, "
1271                    "To force download, set the `force` parameter to `True`."
1272                )
1273
1274        _LOGGER.info(f"Downloading manifest. Location: {complete_path!s}")
1275        data_bytes = await self.read_manifest_bytes(language)
1276        await asyncio.get_running_loop().run_in_executor(
1277            executor, _write_sqlite_bytes, data_bytes, path, name
1278        )
1279        _LOGGER.info("Finished downloading manifest.")
1280        return _get_path(name, path, sql=True)

Downloads the SQLite version of Destiny2's Manifest.

Example
manifest = await rest.download_sqlite_manifest()
with sqlite3.connect(manifest) as conn:
    ...
Parameters
  • language (str): The manifest language to download, Default is English.
  • path (str | pathlib.Path): The path to download this manifest. Example "/tmp/databases/", Default is the current directory.
  • name (str): The manifest database file name. Default is manifest
  • force (bool): Whether to force the download. Default is False. However if set to true the old file will get unlinked and a new one will begin to download.
  • executor (concurrent.futures.Executor | None): An optional executor which will be used to write the bytes of the manifest.
Returns
  • pathlib.Path: A pathlib object of the .sqlite file.
Raises
  • FileExistsError: If the manifest file exists and force is False.
  • ValueError: If the provided language was not recognized.
async def download_json_manifest( self, file_name: 'str' = 'manifest', path: 'str | pathlib.Path' = '.', *, language: '_ALLOWED_LANGS' = 'en', executor: 'concurrent.futures.Executor | None' = None) -> 'pathlib.Path':
1282    async def download_json_manifest(
1283        self,
1284        file_name: str = "manifest",
1285        path: str | pathlib.Path = ".",
1286        *,
1287        language: _ALLOWED_LANGS = "en",
1288        executor: concurrent.futures.Executor | None = None,
1289    ) -> pathlib.Path:
1290        _ensure_manifest_language(language)
1291        full_path = _get_path(file_name, path)
1292        _LOGGER.info(f"Downloading manifest JSON to {full_path!r}...")
1293
1294        content = await self.fetch_manifest_path()
1295        json_bytes = await self._request(
1296            _GET,
1297            content["jsonWorldContentPaths"][language],
1298            unwrap_bytes=True,
1299            base=True,
1300        )
1301
1302        assert isinstance(json_bytes, bytes)
1303        await asyncio.get_running_loop().run_in_executor(
1304            executor, _write_json_bytes, json_bytes, file_name, path
1305        )
1306        _LOGGER.info("Finished downloading manifest JSON.")
1307        return full_path

Download the Bungie manifest json file.

Example
manifest = await rest.download_json_manifest()
with open(manifest, "r") as f:
    to_dict = json.loads(f.read())
    item_definitions = to_dict['DestinyInventoryItemDefinition']
Parameters
  • file_name (str): The file name to save the manifest json file. Default is manifest.
  • path (str | pathlib.Path): The path to save the manifest json file. Default is the current directory. Example "D:/"
  • language (str): The manifest database language bytes to get. Default is English.
  • executor (concurrent.futures.Executor | None): An optional executor which will be used to write the bytes of the manifest.
Returns
  • pathlib.Path: The path of this JSON manifest.
async def fetch_manifest_version(self) -> 'str':
1309    async def fetch_manifest_version(self) -> str:
1310        # This is guaranteed str.
1311        return (await self.fetch_manifest_path())["version"]

Fetch the manifest version.

Returns
  • str: The manifest version.
async def fetch_linked_profiles( self, member_id: 'int', member_type: 'enums.MembershipType | int', /, *, all: 'bool' = False) -> 'typedefs.JSONObject':
1313    async def fetch_linked_profiles(
1314        self,
1315        member_id: int,
1316        member_type: enums.MembershipType | int,
1317        /,
1318        *,
1319        all: bool = False,
1320    ) -> typedefs.JSONObject:
1321        resp = await self._request(
1322            _GET,
1323            f"Destiny2/{int(member_type)}/Profile/{member_id}/LinkedProfiles/?getAllMemberships={all}",
1324        )
1325        assert isinstance(resp, dict)
1326        return resp

Returns a summary information about all profiles linked to the requested member.

The passed membership id/type maybe a Bungie.Net membership or a Destiny memberships.

It will only return linked accounts whose linkages you are allowed to view.

Parameters
  • member_id (int): The ID of the membership. This must be a valid Bungie.Net or PSN or Xbox ID.
  • member_type (aiobungie.aiobungie.MembershipType | int): The type for the membership whose linked Destiny account you want to return.
Other Parameters
  • all (bool): If provided and set to True, All memberships regardless of whether they're obscured by overrides will be returned,

    If provided and set to False, Only available memberships will be returned. The default for this is False.

Returns
async def fetch_clan_banners(self) -> 'typedefs.JSONObject':
1328    async def fetch_clan_banners(self) -> typedefs.JSONObject:
1329        resp = await self._request(_GET, "Destiny2/Clan/ClanBannerDictionary/")
1330        assert isinstance(resp, dict)
1331        return resp

Fetch the values of the clan banners.

Returns
async def fetch_public_milestones(self) -> 'typedefs.JSONObject':
1333    async def fetch_public_milestones(self) -> typedefs.JSONObject:
1334        resp = await self._request(_GET, "Destiny2/Milestones/")
1335        assert isinstance(resp, dict)
1336        return resp

Fetch the available milestones.

Returns
async def fetch_public_milestone_content(self, milestone_hash: 'int', /) -> 'typedefs.JSONObject':
1338    async def fetch_public_milestone_content(
1339        self, milestone_hash: int, /
1340    ) -> typedefs.JSONObject:
1341        resp = await self._request(
1342            _GET, f"Destiny2/Milestones/{milestone_hash}/Content/"
1343        )
1344        assert isinstance(resp, dict)
1345        return resp

Fetch the milestone content given its hash.

Parameters
  • milestone_hash (int): The milestone hash.
Returns
async def fetch_current_user_memberships(self, access_token: 'str', /) -> 'typedefs.JSONObject':
1347    async def fetch_current_user_memberships(
1348        self, access_token: str, /
1349    ) -> typedefs.JSONObject:
1350        resp = await self._request(
1351            _GET,
1352            "User/GetMembershipsForCurrentUser/",
1353            auth=access_token,
1354        )
1355        assert isinstance(resp, dict)
1356        return resp

Fetch a bungie user's accounts with the signed in user. This GET method requires a Bearer access token for the authorization.

This requires OAuth2 scope enabled and the valid Bearer access_token.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
Returns
async def equip_item( self, access_token: 'str', /, item_id: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'None':
1358    async def equip_item(
1359        self,
1360        access_token: str,
1361        /,
1362        item_id: int,
1363        character_id: int,
1364        membership_type: enums.MembershipType | int,
1365    ) -> None:
1366        payload = {
1367            "itemId": item_id,
1368            "characterId": character_id,
1369            "membershipType": int(membership_type),
1370        }
1371
1372        await self._request(
1373            _POST,
1374            "Destiny2/Actions/Items/EquipItem/",
1375            json=payload,
1376            auth=access_token,
1377        )

Equip an item to a character.

This requires the OAuth2: MoveEquipDestinyItems scope. Also You must have a valid Destiny account, and either be in a social space, in orbit or offline.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • item_id (int): The item id.
  • character_id (int): The character's id to equip the item to.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The membership type associated with this player.
async def equip_items( self, access_token: 'str', /, item_ids: 'collections.Sequence[int]', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'None':
1379    async def equip_items(
1380        self,
1381        access_token: str,
1382        /,
1383        item_ids: collections.Sequence[int],
1384        character_id: int,
1385        membership_type: enums.MembershipType | int,
1386    ) -> None:
1387        payload = {
1388            "itemIds": item_ids,
1389            "characterId": character_id,
1390            "membershipType": int(membership_type),
1391        }
1392        await self._request(
1393            _POST,
1394            "Destiny2/Actions/Items/EquipItems/",
1395            json=payload,
1396            auth=access_token,
1397        )

Equip multiple items to a character.

This requires the OAuth2: MoveEquipDestinyItems scope. Also You must have a valid Destiny account, and either be in a social space, in orbit or offline.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • item_ids (Sequence[int]): A sequence of item ids.
  • character_id (int): The character's id to equip the item to.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The membership type associated with this player.
async def ban_clan_member( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', *, length: 'int' = 0, comment: 'str | None' = None) -> 'None':
1399    async def ban_clan_member(
1400        self,
1401        access_token: str,
1402        /,
1403        group_id: int,
1404        membership_id: int,
1405        membership_type: enums.MembershipType | int,
1406        *,
1407        length: int = 0,
1408        comment: str | None = None,
1409    ) -> None:
1410        payload = {"comment": str(comment), "length": length}
1411        await self._request(
1412            _POST,
1413            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Ban/",
1414            json=payload,
1415            auth=access_token,
1416        )

Bans a member from the clan.

This request requires OAuth2: oauth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id.
  • membership_id (int): The member id to ban.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The member's membership type.
Other Parameters
  • length (int): An optional ban length.
  • comment (aiobungie.UndefinedOr[str]): An optional comment to this ban. Default is UNDEFINED
async def unban_clan_member( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'None':
1418    async def unban_clan_member(
1419        self,
1420        access_token: str,
1421        /,
1422        group_id: int,
1423        membership_id: int,
1424        membership_type: enums.MembershipType | int,
1425    ) -> None:
1426        await self._request(
1427            _POST,
1428            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Unban/",
1429            auth=access_token,
1430        )

Unban a member from the clan.

This request requires OAuth2: oauth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id.
  • membership_id (int): The member id to unban.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The member's membership type.
async def kick_clan_member( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
1432    async def kick_clan_member(
1433        self,
1434        access_token: str,
1435        /,
1436        group_id: int,
1437        membership_id: int,
1438        membership_type: enums.MembershipType | int,
1439    ) -> typedefs.JSONObject:
1440        resp = await self._request(
1441            _POST,
1442            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Kick/",
1443            auth=access_token,
1444        )
1445        assert isinstance(resp, dict)
1446        return resp

Kick a member from the clan.

This request requires OAuth2: oauth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id.
  • membership_id (int): The member id to kick.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The member's membership type.
Returns
async def edit_clan( self, access_token: 'str', /, group_id: 'int', *, name: 'str | None' = None, about: 'str | None' = None, motto: 'str | None' = None, theme: 'str | None' = None, tags: 'collections.Sequence[str] | None' = None, is_public: 'bool | None' = None, locale: 'str | None' = None, avatar_image_index: 'int | None' = None, membership_option: 'enums.MembershipOption | int | None' = None, allow_chat: 'bool | None' = None, chat_security: 'typing.Literal[0, 1] | None' = None, call_sign: 'str | None' = None, homepage: 'typing.Literal[0, 1, 2] | None' = None, enable_invite_messaging_for_admins: 'bool | None' = None, default_publicity: 'typing.Literal[0, 1, 2] | None' = None, is_public_topic_admin: 'bool | None' = None) -> 'None':
1448    async def edit_clan(
1449        self,
1450        access_token: str,
1451        /,
1452        group_id: int,
1453        *,
1454        name: str | None = None,
1455        about: str | None = None,
1456        motto: str | None = None,
1457        theme: str | None = None,
1458        tags: collections.Sequence[str] | None = None,
1459        is_public: bool | None = None,
1460        locale: str | None = None,
1461        avatar_image_index: int | None = None,
1462        membership_option: enums.MembershipOption | int | None = None,
1463        allow_chat: bool | None = None,
1464        chat_security: typing.Literal[0, 1] | None = None,
1465        call_sign: str | None = None,
1466        homepage: typing.Literal[0, 1, 2] | None = None,
1467        enable_invite_messaging_for_admins: bool | None = None,
1468        default_publicity: typing.Literal[0, 1, 2] | None = None,
1469        is_public_topic_admin: bool | None = None,
1470    ) -> None:
1471        payload = {
1472            "name": name,
1473            "about": about,
1474            "motto": motto,
1475            "theme": theme,
1476            "tags": tags,
1477            "isPublic": is_public,
1478            "avatarImageIndex": avatar_image_index,
1479            "isPublicTopicAdminOnly": is_public_topic_admin,
1480            "allowChat": allow_chat,
1481            "chatSecurity": chat_security,
1482            "callsign": call_sign,
1483            "homepage": homepage,
1484            "enableInvitationMessagingForAdmins": enable_invite_messaging_for_admins,
1485            "defaultPublicity": default_publicity,
1486            "locale": locale,
1487        }
1488        if membership_option is not None:
1489            payload["membershipOption"] = int(membership_option)
1490
1491        await self._request(
1492            _POST,
1493            f"GroupV2/{group_id}/Edit",
1494            json=payload,
1495            auth=access_token,
1496        )

Edit a clan.

Notes
  • This request requires OAuth2: oauth2: AdminGroups scope.
  • All arguments will default to None if not provided. This does not include access_token and group_id
Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id to edit.
Other Parameters
  • name (str | None): The name to edit the clan with.
  • about (str | None): The about section to edit the clan with.
  • motto (str | None): The motto section to edit the clan with.
  • theme (str | None): The theme name to edit the clan with.
  • tags (collections.Sequence[str] | None): A sequence of strings to replace the clan tags with.
  • is_public (bool | None): If provided and set to True, The clan will set to private. If provided and set to False, The clan will set to public whether it was or not.
  • locale (str | None): The locale section to edit the clan with.
  • avatar_image_index (int | None): The clan avatar image index to edit the clan with.
  • membership_option : aiobungie.typedefs.NoneOr[aiobungie.aiobungie.MembershipOption | int] # noqa (E501 # Line too long): The clan membership option to edit it with.
  • allow_chat (bool | None): If provided and set to True, The clan members will be allowed to chat. If provided and set to False, The clan members will not be allowed to chat.
  • chat_security (aiobungie.typedefs.NoneOr[typing.Literal[0, 1]]): If provided and set to 0, The clan chat security will be edited to Group only. If provided and set to 1, The clan chat security will be edited to Admin only.
  • call_sign (str | None): The clan call sign to edit it with.
  • homepage (aiobungie.typedefs.NoneOr[typing.Literal[0, 1, 2]]): If provided and set to 0, The clan chat homepage will be edited to Wall. If provided and set to 1, The clan chat homepage will be edited to Forum. If provided and set to 0, The clan chat homepage will be edited to AllianceForum.
  • enable_invite_messaging_for_admins (bool | None): ???
  • default_publicity (aiobungie.typedefs.NoneOr[typing.Literal[0, 1, 2]]): If provided and set to 0, The clan chat publicity will be edited to Public. If provided and set to 1, The clan chat publicity will be edited to Alliance. If provided and set to 2, The clan chat publicity will be edited to Private.
  • is_public_topic_admin (bool | None): ???
async def edit_clan_options( self, access_token: 'str', /, group_id: 'int', *, invite_permissions_override: 'bool | None' = None, update_culture_permissionOverride: 'bool | None' = None, host_guided_game_permission_override: 'typing.Literal[0, 1, 2] | None' = None, update_banner_permission_override: 'bool | None' = None, join_level: 'enums.ClanMemberType | int | None' = None) -> 'None':
1498    async def edit_clan_options(
1499        self,
1500        access_token: str,
1501        /,
1502        group_id: int,
1503        *,
1504        invite_permissions_override: bool | None = None,
1505        update_culture_permissionOverride: bool | None = None,
1506        host_guided_game_permission_override: typing.Literal[0, 1, 2] | None = None,
1507        update_banner_permission_override: bool | None = None,
1508        join_level: enums.ClanMemberType | int | None = None,
1509    ) -> None:
1510        payload = {
1511            "InvitePermissionOverride": invite_permissions_override,
1512            "UpdateCulturePermissionOverride": update_culture_permissionOverride,
1513            "HostGuidedGamePermissionOverride": host_guided_game_permission_override,
1514            "UpdateBannerPermissionOverride": update_banner_permission_override,
1515            "JoinLevel": int(join_level) if join_level else None,
1516        }
1517
1518        await self._request(
1519            _POST,
1520            f"GroupV2/{group_id}/EditFounderOptions",
1521            json=payload,
1522            auth=access_token,
1523        )

Edit the clan options.

Notes
  • This request requires OAuth2: oauth2: AdminGroups scope.
  • All arguments will default to None if not provided. This does not include access_token and group_id
Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group id.
Other Parameters
  • invite_permissions_override (bool | None): Minimum Member Level allowed to invite new members to group Always Allowed: Founder, Acting Founder True means admins have this power, false means they don't Default is False for clans, True for groups.
  • update_culture_permissionOverride (bool | None): Minimum Member Level allowed to update group culture Always Allowed: Founder, Acting Founder True means admins have this power, false means they don't Default is False for clans, True for groups.
  • host_guided_game_permission_override (aiobungie.typedefs.NoneOr[typing.Literal[0, 1, 2]]): Minimum Member Level allowed to host guided games Always Allowed: Founder, Acting Founder, Admin Allowed Overrides: 0 -> None, 1 -> Beginner 2 -> Member. Default is Member for clans, None for groups, although this means nothing for groups.
  • update_banner_permission_override (bool | None): Minimum Member Level allowed to update banner Always Allowed: Founder, Acting Founder True means admins have this power, false means they don't Default is False for clans, True for groups.
  • join_level (aiobungie.ClanMemberType): Level to join a member at when accepting an invite, application, or joining an open clan. Default is aiobungie.ClanMemberType.BEGINNER
async def report_player( self, access_token: 'str', /, activity_id: 'int', character_id: 'int', reason_hashes: 'collections.Sequence[int]', reason_category_hashes: 'collections.Sequence[int]') -> 'None':
1525    async def report_player(
1526        self,
1527        access_token: str,
1528        /,
1529        activity_id: int,
1530        character_id: int,
1531        reason_hashes: collections.Sequence[int],
1532        reason_category_hashes: collections.Sequence[int],
1533    ) -> None:
1534        await self._request(
1535            _POST,
1536            f"Destiny2/Stats/PostGameCarnageReport/{activity_id}/Report/",
1537            json={
1538                "reasonCategoryHashes": reason_category_hashes,
1539                "reasonHashes": reason_hashes,
1540                "offendingCharacterId": character_id,
1541            },
1542            auth=access_token,
1543        )

Report a player that you met in an activity that was engaging in ToS-violating activities.

This method requires BnetWrite OAuth2 scope.

Both you and the offending player must have played in the activity_id passed in. Please use this judiciously and only when you have strong suspicions of violation, pretty please.

Parameters
  • access_token (str): The bearer access token associated with the bungie account that will be used to make the request with.
  • activity_id (int): The activity where you ran into the person you're reporting.
  • character_id (int): The character ID of the person you're reporting.
  • reason_hashes (Sequence[int]): See
  • reason_category_hashes (Sequence[int]): See
async def fetch_friends(self, access_token: 'str', /) -> 'typedefs.JSONObject':
1545    async def fetch_friends(self, access_token: str, /) -> typedefs.JSONObject:
1546        resp = await self._request(
1547            _GET,
1548            "Social/Friends/",
1549            auth=access_token,
1550        )
1551        assert isinstance(resp, dict)
1552        return resp

Fetch bungie friend list.

This requests OAuth2: ReadUserData scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
Returns
async def fetch_friend_requests(self, access_token: 'str', /) -> 'typedefs.JSONObject':
1554    async def fetch_friend_requests(self, access_token: str, /) -> typedefs.JSONObject:
1555        resp = await self._request(
1556            _GET,
1557            "Social/Friends/Requests",
1558            auth=access_token,
1559        )
1560        assert isinstance(resp, dict)
1561        return resp

Fetch pending bungie friend requests queue.

This requests OAuth2: ReadUserData scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
Returns
async def accept_friend_request(self, access_token: 'str', /, member_id: 'int') -> 'None':
1563    async def accept_friend_request(self, access_token: str, /, member_id: int) -> None:
1564        await self._request(
1565            _POST,
1566            f"Social/Friends/Requests/Accept/{member_id}",
1567            auth=access_token,
1568        )

Accepts a friend relationship with the target user. The user must be on your incoming friend request list.

This request requires OAuth2: BnetWrite scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • member_id (int): The member's id to accept.
async def send_friend_request(self, access_token: 'str', /, member_id: 'int') -> 'None':
1570    async def send_friend_request(self, access_token: str, /, member_id: int) -> None:
1571        await self._request(
1572            _POST,
1573            f"Social/Friends/Add/{member_id}",
1574            auth=access_token,
1575        )

Requests a friend relationship with the target user.

This request requires OAuth2: BnetWrite scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • member_id (int): The member's id to send the request to.
async def decline_friend_request(self, access_token: 'str', /, member_id: 'int') -> 'None':
1577    async def decline_friend_request(
1578        self, access_token: str, /, member_id: int
1579    ) -> None:
1580        await self._request(
1581            _POST,
1582            f"Social/Friends/Requests/Decline/{member_id}",
1583            auth=access_token,
1584        )

Decline a friend request with the target user. The user must be in your incoming friend request list.

This request requires OAuth2: BnetWrite scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • member_id (int): The member's id to decline.
async def remove_friend(self, access_token: 'str', /, member_id: 'int') -> 'None':
1586    async def remove_friend(self, access_token: str, /, member_id: int) -> None:
1587        await self._request(
1588            _POST,
1589            f"Social/Friends/Remove/{member_id}",
1590            auth=access_token,
1591        )

Removes a friend from your friend list. The user must be in your friend list.

This request requires OAuth2: BnetWrite scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • member_id (int): The member's id to remove.
async def remove_friend_request(self, access_token: 'str', /, member_id: 'int') -> 'None':
1593    async def remove_friend_request(self, access_token: str, /, member_id: int) -> None:
1594        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1595        await self._request(
1596            _POST,
1597            f"Social/Friends/Requests/Remove/{member_id}",
1598            auth=access_token,
1599        )

Removes a friend from your friend list requests. The user must be in your outgoing request list.

.. note : This request requires OAuth2: BnetWrite scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • member_id (int): The member's id to remove from the requested friend list.
async def approve_all_pending_group_users( self, access_token: 'str', /, group_id: 'int', message: 'str | None' = None) -> 'None':
1601    async def approve_all_pending_group_users(
1602        self,
1603        access_token: str,
1604        /,
1605        group_id: int,
1606        message: str | None = None,
1607    ) -> None:
1608        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1609        await self._request(
1610            _POST,
1611            f"GroupV2/{group_id}/Members/ApproveAll",
1612            auth=access_token,
1613            json={"message": str(message)},
1614        )

Approve all pending users for the given group id.

This request requires OAuth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The given group id.
Other Parameters
  • message (aiobungie.UndefinedOr[str]): An optional message to send with the request. Default is UNDEFINED.
async def deny_all_pending_group_users( self, access_token: 'str', /, group_id: 'int', *, message: 'str | None' = None) -> 'None':
1616    async def deny_all_pending_group_users(
1617        self,
1618        access_token: str,
1619        /,
1620        group_id: int,
1621        *,
1622        message: str | None = None,
1623    ) -> None:
1624        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1625        await self._request(
1626            _POST,
1627            f"GroupV2/{group_id}/Members/DenyAll",
1628            auth=access_token,
1629            json={"message": str(message)},
1630        )

Deny all pending users for the given group id.

This request requires OAuth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The given group id.
Other Parameters
  • message (aiobungie.UndefinedOr[str]): An optional message to send with the request. Default is UNDEFINED.
async def add_optional_conversation( self, access_token: 'str', /, group_id: 'int', *, name: 'str | None' = None, security: 'typing.Literal[0, 1]' = 0) -> 'None':
1632    async def add_optional_conversation(
1633        self,
1634        access_token: str,
1635        /,
1636        group_id: int,
1637        *,
1638        name: str | None = None,
1639        security: typing.Literal[0, 1] = 0,
1640    ) -> None:
1641        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1642        payload = {"chatName": str(name), "chatSecurity": security}
1643        await self._request(
1644            _POST,
1645            f"GroupV2/{group_id}/OptionalConversations/Add",
1646            json=payload,
1647            auth=access_token,
1648        )

Add a new chat channel to a group.

This request requires OAuth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The given group id.
Other parameters

name: aiobungie.UndefinedOr[str] The chat name. Default to UNDEFINED security: typing.Literal[0, 1] The security level of the chat.

If provided and set to 0, It will be to `Group` only.
If provided and set to 1, It will be `Admins` only.
Default is `0`
async def edit_optional_conversation( self, access_token: 'str', /, group_id: 'int', conversation_id: 'int', *, name: 'str | None' = None, security: 'typing.Literal[0, 1]' = 0, enable_chat: 'bool' = False) -> 'None':
1650    async def edit_optional_conversation(
1651        self,
1652        access_token: str,
1653        /,
1654        group_id: int,
1655        conversation_id: int,
1656        *,
1657        name: str | None = None,
1658        security: typing.Literal[0, 1] = 0,
1659        enable_chat: bool = False,
1660    ) -> None:
1661        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1662        payload = {
1663            "chatEnabled": enable_chat,
1664            "chatName": str(name),
1665            "chatSecurity": security,
1666        }
1667        await self._request(
1668            _POST,
1669            f"GroupV2/{group_id}/OptionalConversations/Edit/{conversation_id}",
1670            json=payload,
1671            auth=access_token,
1672        )

Edit the settings of this chat channel.

This request requires OAuth2: AdminGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The given group id.
  • conversation_id (int): The conversation/chat id.
Other parameters

name: aiobungie.UndefinedOr[str] The new chat name. Default to UNDEFINED security: typing.Literal[0, 1] The new security level of the chat.

If provided and set to 0, It will be to `Group` only.
If provided and set to 1, It will be `Admins` only.
Default is `0`

enable_chat : bool Whether to enable chatting or not. If set to True then chatting will be enabled. Otherwise it will be disabled.

async def transfer_item( self, access_token: 'str', /, item_id: 'int', item_hash: 'int', character_id: 'int', member_type: 'enums.MembershipType | int', *, stack_size: 'int' = 1, vault: 'bool' = False) -> 'None':
1674    async def transfer_item(
1675        self,
1676        access_token: str,
1677        /,
1678        item_id: int,
1679        item_hash: int,
1680        character_id: int,
1681        member_type: enums.MembershipType | int,
1682        *,
1683        stack_size: int = 1,
1684        vault: bool = False,
1685    ) -> None:
1686        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1687        payload = {
1688            "characterId": character_id,
1689            "membershipType": int(member_type),
1690            "itemId": item_id,
1691            "itemReferenceHash": item_hash,
1692            "stackSize": stack_size,
1693            "transferToVault": vault,
1694        }
1695        await self._request(
1696            _POST,
1697            "Destiny2/Actions/Items/TransferItem",
1698            json=payload,
1699            auth=access_token,
1700        )

Transfer an item from / to your vault.

Notes
  • This method requires OAuth2: MoveEquipDestinyItems scope.
  • This method requires both item id and hash.
Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • item_id (int): The item instance id you to transfer.
  • item_hash (int): The item hash.
  • character_id (int): The character id to transfer the item from/to.
  • member_type (aiobungie.aiobungie.MembershipType | int): The user membership type.
Other Parameters
  • stack_size (int): The item stack size.
  • vault (bool): Whether to transfer this item to your vault or not. Defaults to False.
async def pull_item( self, access_token: 'str', /, item_id: 'int', item_hash: 'int', character_id: 'int', member_type: 'enums.MembershipType | int', *, stack_size: 'int' = 1, vault: 'bool' = False) -> 'None':
1702    async def pull_item(
1703        self,
1704        access_token: str,
1705        /,
1706        item_id: int,
1707        item_hash: int,
1708        character_id: int,
1709        member_type: enums.MembershipType | int,
1710        *,
1711        stack_size: int = 1,
1712        vault: bool = False,
1713    ) -> None:
1714        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1715        payload = {
1716            "characterId": character_id,
1717            "membershipType": int(member_type),
1718            "itemId": item_id,
1719            "itemReferenceHash": item_hash,
1720            "stackSize": stack_size,
1721        }
1722        await self._request(
1723            _POST,
1724            "Destiny2/Actions/Items/PullFromPostmaster",
1725            json=payload,
1726            auth=access_token,
1727        )
1728        if vault:
1729            await self.transfer_item(
1730                access_token,
1731                item_id=item_id,
1732                item_hash=item_hash,
1733                character_id=character_id,
1734                member_type=member_type,
1735                stack_size=stack_size,
1736                vault=True,
1737            )

pull an item from the postmaster.

Notes
  • This method requires OAuth2: MoveEquipDestinyItems scope.
  • This method requires both item id and hash.
Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • item_id (int): The item instance id to pull.
  • item_hash (int): The item hash.
  • character_id (int): The character id to pull the item to.
  • member_type (aiobungie.aiobungie.MembershipType | int): The user membership type.
Other Parameters
  • stack_size (int): The item stack size.
  • vault (bool): If True, an extra HTTP call will be performed to transfer this item to the vault, Defaults to False.
@helpers.unstable
async def fetch_fireteams( self, activity_type: 'fireteams.FireteamActivity | int', *, platform: 'fireteams.FireteamPlatform | int' = <FireteamPlatform.ANY: 0>, language: 'fireteams.FireteamLanguage | str' = <FireteamLanguage.ALL: >, date_range: 'fireteams.FireteamDate | int' = <FireteamDate.ALL: 0>, page: 'int' = 0, slots_filter: 'int' = 0) -> 'typedefs.JSONObject':
1739    @helpers.unstable
1740    async def fetch_fireteams(
1741        self,
1742        activity_type: fireteams.FireteamActivity | int,
1743        *,
1744        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1745        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1746        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1747        page: int = 0,
1748        slots_filter: int = 0,
1749    ) -> typedefs.JSONObject:
1750        resp = await self._request(
1751            _GET,
1752            f"Fireteam/Search/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{page}/?langFilter={str(language)}",  # noqa: E501 Line too long
1753        )
1754        assert isinstance(resp, dict)
1755        return resp

Fetch public Bungie fireteams with open slots.

Parameters
Other Parameters
Returns
async def fetch_available_clan_fireteams( self, access_token: 'str', group_id: 'int', activity_type: 'fireteams.FireteamActivity | int', *, platform: 'fireteams.FireteamPlatform | int', language: 'fireteams.FireteamLanguage | str', date_range: 'fireteams.FireteamDate | int' = <FireteamDate.ALL: 0>, page: 'int' = 0, public_only: 'bool' = False, slots_filter: 'int' = 0) -> 'typedefs.JSONObject':
1757    async def fetch_available_clan_fireteams(
1758        self,
1759        access_token: str,
1760        group_id: int,
1761        activity_type: fireteams.FireteamActivity | int,
1762        *,
1763        platform: fireteams.FireteamPlatform | int,
1764        language: fireteams.FireteamLanguage | str,
1765        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1766        page: int = 0,
1767        public_only: bool = False,
1768        slots_filter: int = 0,
1769    ) -> typedefs.JSONObject:
1770        resp = await self._request(
1771            _GET,
1772            f"Fireteam/Clan/{group_id}/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{public_only}/{page}",  # noqa: E501
1773            json={"langFilter": str(language)},
1774            auth=access_token,
1775        )
1776        assert isinstance(resp, dict)
1777        return resp

Fetch a clan's fireteams with open slots.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id of the fireteam.
  • activity_type (aiobungie.aiobungie.crates.FireteamActivity | int): The fireteam activity type.
Other Parameters
Returns
async def fetch_clan_fireteam( self, access_token: 'str', fireteam_id: 'int', group_id: 'int') -> 'typedefs.JSONObject':
1779    async def fetch_clan_fireteam(
1780        self, access_token: str, fireteam_id: int, group_id: int
1781    ) -> typedefs.JSONObject:
1782        resp = await self._request(
1783            _GET,
1784            f"Fireteam/Clan/{group_id}/Summary/{fireteam_id}",
1785            auth=access_token,
1786        )
1787        assert isinstance(resp, dict)
1788        return resp

Fetch a specific clan fireteam.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id to fetch the fireteam from.
  • fireteam_id (int): The fireteam id to fetch.
Returns
async def fetch_my_clan_fireteams( self, access_token: 'str', group_id: 'int', *, include_closed: 'bool' = True, platform: 'fireteams.FireteamPlatform | int', language: 'fireteams.FireteamLanguage | str', filtered: 'bool' = True, page: 'int' = 0) -> 'typedefs.JSONObject':
1790    async def fetch_my_clan_fireteams(
1791        self,
1792        access_token: str,
1793        group_id: int,
1794        *,
1795        include_closed: bool = True,
1796        platform: fireteams.FireteamPlatform | int,
1797        language: fireteams.FireteamLanguage | str,
1798        filtered: bool = True,
1799        page: int = 0,
1800    ) -> typedefs.JSONObject:
1801        payload = {"groupFilter": filtered, "langFilter": str(language)}
1802
1803        resp = await self._request(
1804            _GET,
1805            f"Fireteam/Clan/{group_id}/My/{int(platform)}/{include_closed}/{page}",
1806            json=payload,
1807            auth=access_token,
1808        )
1809        assert isinstance(resp, dict)
1810        return resp

Fetch a clan's fireteams with open slots.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id to fetch.
Other Parameters
Returns
async def fetch_private_clan_fireteams(self, access_token: 'str', group_id: 'int', /) -> 'int':
1812    async def fetch_private_clan_fireteams(
1813        self, access_token: str, group_id: int, /
1814    ) -> int:
1815        resp = await self._request(
1816            _GET,
1817            f"Fireteam/Clan/{group_id}/ActiveCount",
1818            auth=access_token,
1819        )
1820        assert isinstance(resp, int)
1821        return resp

Fetch the active count of the clan fireteams that are only private.

This method requires OAuth2: ReadGroups scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • group_id (int): The group/clan id.
Returns
  • int: The active fireteams count. Max value returned is 25.
async def fetch_post_activity(self, instance_id: 'int', /) -> 'typedefs.JSONObject':
1823    async def fetch_post_activity(self, instance_id: int, /) -> typedefs.JSONObject:
1824        resp = await self._request(
1825            _GET, f"Destiny2/Stats/PostGameCarnageReport/{instance_id}"
1826        )
1827        assert isinstance(resp, dict)
1828        return resp

Fetch a post activity details.

Parameters
  • instance_id (int): The activity instance id.
Returns
@helpers.unstable
async def search_entities( self, name: 'str', entity_type: 'str', *, page: 'int' = 0) -> 'typedefs.JSONObject':
1830    @helpers.unstable
1831    async def search_entities(
1832        self, name: str, entity_type: str, *, page: int = 0
1833    ) -> typedefs.JSONObject:
1834        resp = await self._request(
1835            _GET,
1836            f"Destiny2/Armory/Search/{entity_type}/{name}/",
1837            json={"page": page},
1838        )
1839        assert isinstance(resp, dict)
1840        return resp

Search for Destiny2 entities given a name and its type.

Parameters
  • name (str): The name of the entity, i.e., Thunderlord, One thousand voices.
  • entity_type (str): The type of the entity, AKA Definition, For an example DestinyInventoryItemDefinition
Other Parameters
  • page (int): An optional page to return. Default to 0.
Returns
async def fetch_unique_weapon_history( self, membership_id: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
1842    async def fetch_unique_weapon_history(
1843        self,
1844        membership_id: int,
1845        character_id: int,
1846        membership_type: enums.MembershipType | int,
1847    ) -> typedefs.JSONObject:
1848        resp = await self._request(
1849            _GET,
1850            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/UniqueWeapons/",
1851        )
1852        assert isinstance(resp, dict)
1853        return resp

Fetch details about unique weapon usage for a character. Includes all exotics.

Parameters
  • membership_id (int): The Destiny user membership id.
  • character_id (int): The character id to retrieve.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The Destiny user's membership type.
Returns
async def fetch_item( self, member_id: 'int', item_id: 'int', membership_type: 'enums.MembershipType | int', components: 'collections.Sequence[enums.ComponentType]') -> 'typedefs.JSONObject':
1855    async def fetch_item(
1856        self,
1857        member_id: int,
1858        item_id: int,
1859        membership_type: enums.MembershipType | int,
1860        components: collections.Sequence[enums.ComponentType],
1861    ) -> typedefs.JSONObject:
1862        collector = _collect_components(components)
1863
1864        resp = await self._request(
1865            _GET,
1866            f"Destiny2/{int(membership_type)}/Profile/{member_id}/Item/{item_id}/?components={collector}",
1867        )
1868        assert isinstance(resp, dict)
1869        return resp

Fetch an instanced Destiny 2 item's details.

Parameters
  • member_id (int): The membership id of the Destiny 2 player.
  • item_id (int): The instance id of the item.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The membership type of the Destiny 2 player.
  • components (collections.Sequence[aiobungie.ComponentType]): A list of components to retrieve.
Returns
async def fetch_clan_weekly_rewards(self, clan_id: 'int', /) -> 'typedefs.JSONObject':
1871    async def fetch_clan_weekly_rewards(self, clan_id: int, /) -> typedefs.JSONObject:
1872        resp = await self._request(_GET, f"Destiny2/Clan/{clan_id}/WeeklyRewardState/")
1873        assert isinstance(resp, dict)
1874        return resp

Fetch the weekly reward state for a clan.

Parameters
  • clan_id (int): The clan id.
Returns
async def fetch_available_locales(self) -> 'typedefs.JSONObject':
1876    async def fetch_available_locales(self) -> typedefs.JSONObject:
1877        resp = await self._request(_GET, "Destiny2/Manifest/DestinyLocaleDefinition/")
1878        assert isinstance(resp, dict)
1879        return resp

Fetch available locales at Bungie.

Returns
async def fetch_common_settings(self) -> 'typedefs.JSONObject':
1881    async def fetch_common_settings(self) -> typedefs.JSONObject:
1882        resp = await self._request(_GET, "Settings")
1883        assert isinstance(resp, dict)
1884        return resp

Fetch the common settings used by Bungie's environment.

Returns
async def fetch_user_systems_overrides(self) -> 'typedefs.JSONObject':
1886    async def fetch_user_systems_overrides(self) -> typedefs.JSONObject:
1887        resp = await self._request(_GET, "UserSystemOverrides")
1888        assert isinstance(resp, dict)
1889        return resp

Fetch a user's specific system overrides.

Returns
async def fetch_global_alerts(self, *, include_streaming: 'bool' = False) -> 'typedefs.JSONArray':
1891    async def fetch_global_alerts(
1892        self, *, include_streaming: bool = False
1893    ) -> typedefs.JSONArray:
1894        resp = await self._request(
1895            _GET, f"GlobalAlerts/?includestreaming={include_streaming}"
1896        )
1897        assert isinstance(resp, list)
1898        return resp

Fetch any active global alerts.

Parameters
  • include_streaming (bool): If True, the returned results will include streaming alerts. Default is False.
Returns
async def awainitialize_request( self, access_token: 'str', type: 'typing.Literal[0, 1]', membership_type: 'enums.MembershipType | int', /, *, affected_item_id: 'int | None' = None, character_id: 'int | None' = None) -> 'typedefs.JSONObject':
1900    async def awainitialize_request(
1901        self,
1902        access_token: str,
1903        type: typing.Literal[0, 1],
1904        membership_type: enums.MembershipType | int,
1905        /,
1906        *,
1907        affected_item_id: int | None = None,
1908        character_id: int | None = None,
1909    ) -> typedefs.JSONObject:
1910        body = {"type": type, "membershipType": int(membership_type)}
1911
1912        if affected_item_id is not None:
1913            body["affectedItemId"] = affected_item_id
1914
1915        if character_id is not None:
1916            body["characterId"] = character_id
1917
1918        resp = await self._request(
1919            _POST, "Destiny2/Awa/Initialize", json=body, auth=access_token
1920        )
1921        assert isinstance(resp, dict)
1922        return resp

Initialize a request to perform an advanced write action.

OAuth2: AdvancedWriteActions application scope is required to perform this request.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • type (typing.Literal[0, 1]): Type of the advanced write action. Its either 0 or 1. If set to 0 that means it None. Otherwise if 1 that means its insert plugs.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The Destiny membership type of the account to modify.
Other Parameters
  • affected_item_id (int | None): Item instance ID the action shall be applied to. This is optional for all but a new AwaType values.
  • character_id (int | None): The Destiny character ID to perform this action on.
Returns
async def awaget_action_token( self, access_token: 'str', correlation_id: 'str', /) -> 'typedefs.JSONObject':
1924    async def awaget_action_token(
1925        self, access_token: str, correlation_id: str, /
1926    ) -> typedefs.JSONObject:
1927        resp = await self._request(
1928            _POST,
1929            f"Destiny2/Awa/GetActionToken/{correlation_id}",
1930            auth=access_token,
1931        )
1932        assert isinstance(resp, dict)
1933        return resp

Returns the action token if user approves the request.

OAuth2: AdvancedWriteActions application scope is required to perform this request.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • correlation_id (str): The identifier for the advanced write action request.
Returns
async def awa_provide_authorization_result( self, access_token: 'str', selection: 'int', correlation_id: 'str', nonce: 'collections.MutableSequence[str | bytes]') -> 'int':
1935    async def awa_provide_authorization_result(
1936        self,
1937        access_token: str,
1938        selection: int,
1939        correlation_id: str,
1940        nonce: collections.MutableSequence[str | bytes],
1941    ) -> int:
1942        body = {"selection": selection, "correlationId": correlation_id, "nonce": nonce}
1943
1944        resp = await self._request(
1945            _POST,
1946            "Destiny2/Awa/AwaProvideAuthorizationResult",
1947            json=body,
1948            auth=access_token,
1949        )
1950        assert isinstance(resp, int)
1951        return resp

Provide the result of the user interaction. Called by the Bungie Destiny App to approve or reject a request.

OAuth2: AdvancedWriteActions application scope is required to perform this request.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • selection (int): Indication of the selection the user has made (Approving or rejecting the action)
  • correlation_id (str): Correlation ID of the request.
  • nonce (collections.MutableSequence[str | bytes]): Secret nonce received via the PUSH notification.
Returns
  • int: ...
async def fetch_vendors( self, access_token: 'str', character_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', /, components: 'collections.Sequence[enums.ComponentType]', filter: 'int | None' = None) -> 'typedefs.JSONObject':
1953    async def fetch_vendors(
1954        self,
1955        access_token: str,
1956        character_id: int,
1957        membership_id: int,
1958        membership_type: enums.MembershipType | int,
1959        /,
1960        components: collections.Sequence[enums.ComponentType],
1961        filter: int | None = None,
1962    ) -> typedefs.JSONObject:
1963        components_ = _collect_components(components)
1964        route = (
1965            f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1966            f"/Character/{character_id}/Vendors/?components={components_}"
1967        )
1968
1969        if filter is not None:
1970            route = route + f"&filter={filter}"
1971
1972        resp = await self._request(
1973            _GET,
1974            route,
1975            auth=access_token,
1976        )
1977        assert isinstance(resp, dict)
1978        return resp

Get currently available vendors from the list of vendors that can possibly have rotating inventory.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • character_id (int): The character ID to return the vendor info for.
  • membership_id (int): The Destiny membership id to return the vendor info for.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The Destiny membership type to return the vendor info for.
  • components (collections.Sequence[aiobungie.ComponentType]): A list of vendor components to collect and return.
Other Parameters
  • filter (int): Filters the type of items returned from the vendor. This can be left to None.
Returns
async def fetch_vendor( self, access_token: 'str', character_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', vendor_hash: 'int', /, components: 'collections.Sequence[enums.ComponentType]') -> 'typedefs.JSONObject':
1980    async def fetch_vendor(
1981        self,
1982        access_token: str,
1983        character_id: int,
1984        membership_id: int,
1985        membership_type: enums.MembershipType | int,
1986        vendor_hash: int,
1987        /,
1988        components: collections.Sequence[enums.ComponentType],
1989    ) -> typedefs.JSONObject:
1990        components_ = _collect_components(components)
1991        resp = await self._request(
1992            _GET,
1993            (
1994                f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1995                f"/Character/{character_id}/Vendors/{vendor_hash}/?components={components_}"
1996            ),
1997            auth=access_token,
1998        )
1999        assert isinstance(resp, dict)
2000        return resp

Fetch details for a specific vendor.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • character_id (int): The character ID to return the vendor info for.
  • membership_id (int): The Destiny membership id to return the vendor info for.
  • membership_type (aiobungie.aiobungie.MembershipType | int): The Destiny membership type to return the vendor info for.
  • vendor_hash (int): The vendor hash to return the details for.
  • components (collections.Sequence[aiobungie.ComponentType]): A list of vendor components to collect and return.
Returns
async def fetch_application_api_usage( self, access_token: 'str', application_id: 'int', /, *, start: 'datetime.datetime | None' = None, end: 'datetime.datetime | None' = None) -> 'typedefs.JSONObject':
2002    async def fetch_application_api_usage(
2003        self,
2004        access_token: str,
2005        application_id: int,
2006        /,
2007        *,
2008        start: datetime.datetime | None = None,
2009        end: datetime.datetime | None = None,
2010    ) -> typedefs.JSONObject:
2011        end_date, start_date = time.parse_date_range(end, start)
2012        resp = await self._request(
2013            _GET,
2014            f"App/ApiUsage/{application_id}/?end={end_date}&start={start_date}",
2015            auth=access_token,
2016        )
2017        assert isinstance(resp, dict)
2018        return resp

Fetch a Bungie application's API usage.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • application_id (int): The application id to get.
Other Parameters
  • start (datetime.datetime | None): A datetime object can be used to collect the start of the application usage. This is limited and can go back to 30 days maximum.

    If this is left to None. It will return the last 24 hours.

  • end (datetime.datetime | None): A datetime object can be used to collect the end of the application usage.

    If this is left to None. It will return now.

Example
import datetime

# Fetch data from 2021 Dec 10th to 2021 Dec 20th
await fetch_application_api_usage(
    start=datetime.datetime(2021, 12, 10),
    end=datetime.datetime(2021, 12, 20)
)
Returns
async def fetch_bungie_applications(self) -> 'typedefs.JSONArray':
2020    async def fetch_bungie_applications(self) -> typedefs.JSONArray:
2021        resp = await self._request(_GET, "App/FirstParty")
2022        assert isinstance(resp, list)
2023        return resp

Fetch details for applications created by Bungie.

Returns
async def fetch_content_type(self, type: 'str', /) -> 'typedefs.JSONObject':
2025    async def fetch_content_type(self, type: str, /) -> typedefs.JSONObject:
2026        resp = await self._request(_GET, f"Content/GetContentType/{type}/")
2027        assert isinstance(resp, dict)
2028        return resp
async def fetch_content_by_id( self, id: 'int', locale: 'str', /, *, head: 'bool' = False) -> 'typedefs.JSONObject':
2030    async def fetch_content_by_id(
2031        self, id: int, locale: str, /, *, head: bool = False
2032    ) -> typedefs.JSONObject:
2033        resp = await self._request(
2034            _GET,
2035            f"Content/GetContentById/{id}/{locale}/",
2036            json={"head": head},
2037        )
2038        assert isinstance(resp, dict)
2039        return resp
async def fetch_content_by_tag_and_type( self, locale: 'str', tag: 'str', type: 'str', *, head: 'bool' = False) -> 'typedefs.JSONObject':
2041    async def fetch_content_by_tag_and_type(
2042        self, locale: str, tag: str, type: str, *, head: bool = False
2043    ) -> typedefs.JSONObject:
2044        resp = await self._request(
2045            _GET,
2046            f"Content/GetContentByTagAndType/{tag}/{type}/{locale}/",
2047            json={"head": head},
2048        )
2049        assert isinstance(resp, dict)
2050        return resp
async def search_content_with_text( self, locale: 'str', /, content_type: 'str', search_text: 'str', tag: 'str', *, page: 'int | None' = None, source: 'str | None' = None) -> 'typedefs.JSONObject':
2052    async def search_content_with_text(
2053        self,
2054        locale: str,
2055        /,
2056        content_type: str,
2057        search_text: str,
2058        tag: str,
2059        *,
2060        page: int | None = None,
2061        source: str | None = None,
2062    ) -> typedefs.JSONObject:
2063        body: typedefs.JSONObject = {
2064            "locale": locale,
2065            "currentpage": page or 1,
2066            "ctype": content_type,
2067            "searchtxt": search_text,
2068            "searchtext": search_text,
2069            "tag": tag,
2070            "source": source,
2071        }
2072
2073        resp = await self._request(_GET, "Content/Search", params=body)
2074        assert isinstance(resp, dict)
2075        return resp
async def search_content_by_tag_and_type( self, locale: 'str', tag: 'str', type: 'str', *, page: 'int | None' = None) -> 'typedefs.JSONObject':
2077    async def search_content_by_tag_and_type(
2078        self,
2079        locale: str,
2080        tag: str,
2081        type: str,
2082        *,
2083        page: int | None = None,
2084    ) -> typedefs.JSONObject:
2085        body: typedefs.JSONObject = {"currentpage": page or 1}
2086
2087        resp = await self._request(
2088            _GET,
2089            f"Content/SearchContentByTagAndType/{tag}/{type}/{locale}/",
2090            params=body,
2091        )
2092        assert isinstance(resp, dict)
2093        return resp
async def search_help_articles(self, text: 'str', size: 'str', /) -> 'typedefs.JSONObject':
2095    async def search_help_articles(
2096        self, text: str, size: str, /
2097    ) -> typedefs.JSONObject:
2098        resp = await self._request(_GET, f"Content/SearchHelpArticles/{text}/{size}/")
2099        assert isinstance(resp, dict)
2100        return resp
async def fetch_topics_page( self, category_filter: 'int', group: 'int', date_filter: 'int', sort: 'str | bytes', *, page: 'int | None' = None, locales: 'collections.Iterable[str] | None' = None, tag_filter: 'str | None' = None) -> 'typedefs.JSONObject':
2102    async def fetch_topics_page(
2103        self,
2104        category_filter: int,
2105        group: int,
2106        date_filter: int,
2107        sort: str | bytes,
2108        *,
2109        page: int | None = None,
2110        locales: collections.Iterable[str] | None = None,
2111        tag_filter: str | None = None,
2112    ) -> typedefs.JSONObject:
2113        params = {
2114            "locales": ",".join(locales) if locales is not None else "en",
2115        }
2116        if tag_filter:
2117            params["tagstring"] = tag_filter
2118
2119        resp = await self._request(
2120            _GET,
2121            f"Forum/GetTopicsPaged/{page or 0}/0/{group}/{sort!s}/{date_filter}/{category_filter}/",
2122            params=params,
2123        )
2124        assert isinstance(resp, dict)
2125        return resp
async def fetch_core_topics_page( self, category_filter: 'int', date_filter: 'int', sort: 'str | bytes', *, page: 'int | None' = None, locales: 'collections.Iterable[str] | None' = None) -> 'typedefs.JSONObject':
2127    async def fetch_core_topics_page(
2128        self,
2129        category_filter: int,
2130        date_filter: int,
2131        sort: str | bytes,
2132        *,
2133        page: int | None = None,
2134        locales: collections.Iterable[str] | None = None,
2135    ) -> typedefs.JSONObject:
2136        resp = await self._request(
2137            _GET,
2138            f"Forum/GetCoreTopicsPaged/{page or 0}"
2139            f"/{sort!s}/{date_filter}/{category_filter}/?locales={','.join(locales) if locales else 'en'}",
2140        )
2141        assert isinstance(resp, dict)
2142        return resp
async def fetch_posts_threaded_page( self, parent_post: 'bool', page: 'int', page_size: 'int', parent_post_id: 'int', reply_size: 'int', root_thread_mode: 'bool', sort_mode: 'int', show_banned: 'str | None' = None) -> 'typedefs.JSONObject':
2144    async def fetch_posts_threaded_page(
2145        self,
2146        parent_post: bool,
2147        page: int,
2148        page_size: int,
2149        parent_post_id: int,
2150        reply_size: int,
2151        root_thread_mode: bool,
2152        sort_mode: int,
2153        show_banned: str | None = None,
2154    ) -> typedefs.JSONObject:
2155        resp = await self._request(
2156            _GET,
2157            f"Forum/GetPostsThreadedPaged/{parent_post}/{page}/"
2158            f"{page_size}/{reply_size}/{parent_post_id}/{root_thread_mode}/{sort_mode}/",
2159            json={"showbanned": show_banned},
2160        )
2161        assert isinstance(resp, dict)
2162        return resp
async def fetch_posts_threaded_page_from_child( self, child_id: 'bool', page: 'int', page_size: 'int', reply_size: 'int', root_thread_mode: 'bool', sort_mode: 'int', show_banned: 'str | None' = None) -> 'typedefs.JSONObject':
2164    async def fetch_posts_threaded_page_from_child(
2165        self,
2166        child_id: bool,
2167        page: int,
2168        page_size: int,
2169        reply_size: int,
2170        root_thread_mode: bool,
2171        sort_mode: int,
2172        show_banned: str | None = None,
2173    ) -> typedefs.JSONObject:
2174        resp = await self._request(
2175            _GET,
2176            f"Forum/GetPostsThreadedPagedFromChild/{child_id}/"
2177            f"{page}/{page_size}/{reply_size}/{root_thread_mode}/{sort_mode}/",
2178            json={"showbanned": show_banned},
2179        )
2180        assert isinstance(resp, dict)
2181        return resp
async def fetch_post_and_parent( self, child_id: 'int', /, *, show_banned: 'str | None' = None) -> 'typedefs.JSONObject':
2183    async def fetch_post_and_parent(
2184        self, child_id: int, /, *, show_banned: str | None = None
2185    ) -> typedefs.JSONObject:
2186        resp = await self._request(
2187            _GET,
2188            f"Forum/GetPostAndParent/{child_id}/",
2189            json={"showbanned": show_banned},
2190        )
2191        assert isinstance(resp, dict)
2192        return resp
async def fetch_posts_and_parent_awaiting( self, child_id: 'int', /, *, show_banned: 'str | None' = None) -> 'typedefs.JSONObject':
2194    async def fetch_posts_and_parent_awaiting(
2195        self, child_id: int, /, *, show_banned: str | None = None
2196    ) -> typedefs.JSONObject:
2197        resp = await self._request(
2198            _GET,
2199            f"Forum/GetPostAndParentAwaitingApproval/{child_id}/",
2200            json={"showbanned": show_banned},
2201        )
2202        assert isinstance(resp, dict)
2203        return resp
async def fetch_topic_for_content(self, content_id: 'int', /) -> 'int':
2205    async def fetch_topic_for_content(self, content_id: int, /) -> int:
2206        resp = await self._request(_GET, f"Forum/GetTopicForContent/{content_id}/")
2207        assert isinstance(resp, int)
2208        return resp
async def fetch_forum_tag_suggestions(self, partial_tag: 'str', /) -> 'typedefs.JSONObject':
2210    async def fetch_forum_tag_suggestions(
2211        self, partial_tag: str, /
2212    ) -> typedefs.JSONObject:
2213        resp = await self._request(
2214            _GET,
2215            "Forum/GetForumTagSuggestions/",
2216            json={"partialtag": partial_tag},
2217        )
2218        assert isinstance(resp, dict)
2219        return resp
async def fetch_poll(self, topic_id: 'int', /) -> 'typedefs.JSONObject':
2221    async def fetch_poll(self, topic_id: int, /) -> typedefs.JSONObject:
2222        resp = await self._request(_GET, f"Forum/Poll/{topic_id}/")
2223        assert isinstance(resp, dict)
2224        return resp
async def fetch_recruitment_thread_summaries(self) -> 'typedefs.JSONArray':
2226    async def fetch_recruitment_thread_summaries(self) -> typedefs.JSONArray:
2227        resp = await self._request(_POST, "Forum/Recruit/Summaries/")
2228        assert isinstance(resp, list)
2229        return resp
async def fetch_available_avatars(self) -> 'collections.Mapping[str, int]':
2247    async def fetch_available_avatars(self) -> collections.Mapping[str, int]:
2248        resp = await self._request(_GET, "GroupV2/GetAvailableAvatars/")
2249        assert isinstance(resp, dict)
2250        return resp
async def fetch_user_clan_invite_setting( self, access_token: 'str', /, membership_type: 'enums.MembershipType | int') -> 'bool':
2252    async def fetch_user_clan_invite_setting(
2253        self,
2254        access_token: str,
2255        /,
2256        membership_type: enums.MembershipType | int,
2257    ) -> bool:
2258        resp = await self._request(
2259            _GET,
2260            f"GroupV2/GetUserClanInviteSetting/{int(membership_type)}/",
2261            auth=access_token,
2262        )
2263        assert isinstance(resp, bool)
2264        return resp
async def fetch_banned_group_members( self, access_token: 'str', group_id: 'int', /, *, page: 'int' = 1) -> 'typedefs.JSONObject':
2266    async def fetch_banned_group_members(
2267        self, access_token: str, group_id: int, /, *, page: int = 1
2268    ) -> typedefs.JSONObject:
2269        resp = await self._request(
2270            _GET,
2271            f"GroupV2/{group_id}/Banned/?currentpage={page}",
2272            auth=access_token,
2273        )
2274        assert isinstance(resp, dict)
2275        return resp
async def fetch_pending_group_memberships( self, access_token: 'str', group_id: 'int', /, *, current_page: 'int' = 1) -> 'typedefs.JSONObject':
2277    async def fetch_pending_group_memberships(
2278        self, access_token: str, group_id: int, /, *, current_page: int = 1
2279    ) -> typedefs.JSONObject:
2280        resp = await self._request(
2281            _GET,
2282            f"GroupV2/{group_id}/Members/Pending/?currentpage={current_page}",
2283            auth=access_token,
2284        )
2285        assert isinstance(resp, dict)
2286        return resp
async def fetch_invited_group_memberships( self, access_token: 'str', group_id: 'int', /, *, current_page: 'int' = 1) -> 'typedefs.JSONObject':
2288    async def fetch_invited_group_memberships(
2289        self, access_token: str, group_id: int, /, *, current_page: int = 1
2290    ) -> typedefs.JSONObject:
2291        resp = await self._request(
2292            _GET,
2293            f"GroupV2/{group_id}/Members/InvitedIndividuals/?currentpage={current_page}",
2294            auth=access_token,
2295        )
2296        assert isinstance(resp, dict)
2297        return resp
async def invite_member_to_group( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', *, message: 'str | None' = None) -> 'typedefs.JSONObject':
2299    async def invite_member_to_group(
2300        self,
2301        access_token: str,
2302        /,
2303        group_id: int,
2304        membership_id: int,
2305        membership_type: enums.MembershipType | int,
2306        *,
2307        message: str | None = None,
2308    ) -> typedefs.JSONObject:
2309        resp = await self._request(
2310            _POST,
2311            f"GroupV2/{group_id}/Members/IndividualInvite/{int(membership_type)}/{membership_id}/",
2312            auth=access_token,
2313            json={"message": str(message)},
2314        )
2315        assert isinstance(resp, dict)
2316        return resp
async def cancel_group_member_invite( self, access_token: 'str', /, group_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
2318    async def cancel_group_member_invite(
2319        self,
2320        access_token: str,
2321        /,
2322        group_id: int,
2323        membership_id: int,
2324        membership_type: enums.MembershipType | int,
2325    ) -> typedefs.JSONObject:
2326        resp = await self._request(
2327            _POST,
2328            f"GroupV2/{group_id}/Members/IndividualInviteCancel/{int(membership_type)}/{membership_id}/",
2329            auth=access_token,
2330        )
2331        assert isinstance(resp, dict)
2332        return resp
async def fetch_historical_definition(self) -> 'typedefs.JSONObject':
2334    async def fetch_historical_definition(self) -> typedefs.JSONObject:
2335        resp = await self._request(_GET, "Destiny2/Stats/Definition/")
2336        assert isinstance(resp, dict)
2337        return resp
async def fetch_historical_stats( self, character_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', day_start: 'datetime.datetime', day_end: 'datetime.datetime', groups: 'collections.Sequence[enums.StatsGroupType | int]', modes: 'collections.Sequence[enums.GameMode | int]', *, period_type: 'enums.PeriodType' = <PeriodType.ALL_TIME: 2>) -> 'typedefs.JSONObject':
2339    async def fetch_historical_stats(
2340        self,
2341        character_id: int,
2342        membership_id: int,
2343        membership_type: enums.MembershipType | int,
2344        day_start: datetime.datetime,
2345        day_end: datetime.datetime,
2346        groups: collections.Sequence[enums.StatsGroupType | int],
2347        modes: collections.Sequence[enums.GameMode | int],
2348        *,
2349        period_type: enums.PeriodType = enums.PeriodType.ALL_TIME,
2350    ) -> typedefs.JSONObject:
2351        end, start = time.parse_date_range(day_end, day_start)
2352        resp = await self._request(
2353            _GET,
2354            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/",
2355            json={
2356                "dayend": end,
2357                "daystart": start,
2358                "groups": [str(int(group)) for group in groups],
2359                "modes": [str(int(mode)) for mode in modes],
2360                "periodType": int(period_type),
2361            },
2362        )
2363        assert isinstance(resp, dict)
2364        return resp

Fetch historical stats for a specific membership character.

Parameters
  • character_id (int): The character ID to return the stats for.
  • membership_id (int): The Destiny membership id to return the stats for.
  • membership_type (aiobungie.MembershipType | int): The Destiny membership type to return the stats for.
  • day_start (datetime.datetime): The start of the day to return the stats for.
  • day_end (datetime.datetime): The end of the day to return the stats for.
  • groups (collections.Sequence[aiobungie.StatsGroupType]): A list of stats groups to return.
  • modes (collections.Sequence[aiobungie.GameMode | int]): A list of game modes to return.
  • period_type (aiobungie.enums.PeriodType): The period type to return the stats for. This will return ALL_TIME by default if not modified.
Returns
async def fetch_historical_stats_for_account( self, membership_id: 'int', membership_type: 'enums.MembershipType | int', groups: 'collections.Sequence[enums.StatsGroupType | int]') -> 'typedefs.JSONObject':
2366    async def fetch_historical_stats_for_account(
2367        self,
2368        membership_id: int,
2369        membership_type: enums.MembershipType | int,
2370        groups: collections.Sequence[enums.StatsGroupType | int],
2371    ) -> typedefs.JSONObject:
2372        resp = await self._request(
2373            _GET,
2374            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Stats/",
2375            json={"groups": [str(int(group)) for group in groups]},
2376        )
2377        assert isinstance(resp, dict)
2378        return resp

Fetch historical stats for an account's membership.

Parameters
  • membership_id (int): The Destiny membership id to return the stats for.
  • membership_type (aiobungie.MembershipType | int): The Destiny membership type to return the stats for.
  • groups (collections.Sequence[aiobungie.StatsGroupType]): A list of stats groups to return.
Returns
async def fetch_aggregated_activity_stats( self, character_id: 'int', membership_id: 'int', membership_type: 'enums.MembershipType | int', /) -> 'typedefs.JSONObject':
2380    async def fetch_aggregated_activity_stats(
2381        self,
2382        character_id: int,
2383        membership_id: int,
2384        membership_type: enums.MembershipType | int,
2385        /,
2386    ) -> typedefs.JSONObject:
2387        resp = await self._request(
2388            _GET,
2389            f"Destiny2/{int(membership_type)}/Account/{membership_id}/"
2390            f"Character/{character_id}/Stats/AggregateActivityStats/",
2391        )
2392        assert isinstance(resp, dict)
2393        return resp

Fetch aggregated activity stats for a specific membership character.

Parameters
  • character_id (int): The character ID to return the stats for.
  • membership_id (int): The Destiny membership id to return the stats for.
  • membership_type (aiobungie.MembershipType | int): The Destiny membership type to return the stats for.
Returns
async def equip_loadout( self, access_token: 'str', /, loadout_index: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'None':
2395    async def equip_loadout(
2396        self,
2397        access_token: str,
2398        /,
2399        loadout_index: int,
2400        character_id: int,
2401        membership_type: enums.MembershipType | int,
2402    ) -> None:
2403        response = await self._request(
2404            _POST,
2405            "Destiny2/Actions/Loadouts/EquipLoadout/",
2406            json={
2407                "loadoutIndex": loadout_index,
2408                "characterId": character_id,
2409                "membership_type": int(membership_type),
2410            },
2411            auth=access_token,
2412        )
2413        assert isinstance(response, int)

Equip a loadout. Your character must be in a Social space, Orbit or Offline while performing this operation.

This operation requires MoveEquipDestinyItems OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • loadout_index (int): The index of the loadout to use.
  • character_id (int): The character ID to equip the loadout to.
  • membership_type (aiobungie.MembershipType | int): The membership type of the account.
async def snapshot_loadout( self, access_token: 'str', /, loadout_index: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int', *, color_hash: 'int | None' = None, icon_hash: 'int | None' = None, name_hash: 'int | None' = None) -> 'None':
2415    async def snapshot_loadout(
2416        self,
2417        access_token: str,
2418        /,
2419        loadout_index: int,
2420        character_id: int,
2421        membership_type: enums.MembershipType | int,
2422        *,
2423        color_hash: int | None = None,
2424        icon_hash: int | None = None,
2425        name_hash: int | None = None,
2426    ) -> None:
2427        response = await self._request(
2428            _POST,
2429            "Destiny2/Actions/Loadouts/SnapshotLoadout/",
2430            auth=access_token,
2431            json={
2432                "colorHash": color_hash,
2433                "iconHash": icon_hash,
2434                "nameHash": name_hash,
2435                "loadoutIndex": loadout_index,
2436                "characterId": character_id,
2437                "membershipType": int(membership_type),
2438            },
2439        )
2440        assert isinstance(response, int)

Snapshot a loadout with the currently equipped items.

This operation requires MoveEquipDestinyItems OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • loadout_index (int): The index of the loadout to use.
  • character_id (int): The character ID to equip the loadout to.
  • membership_type (aiobungie.MembershipType | int): The membership type of the account.
Other Parameters
  • color_hash (int | None): ...
  • icon_hash (int | None): ...
  • name_hash (int | None): ...
async def update_loadout( self, access_token: 'str', /, loadout_index: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int', *, color_hash: 'int | None' = None, icon_hash: 'int | None' = None, name_hash: 'int | None' = None) -> 'None':
2442    async def update_loadout(
2443        self,
2444        access_token: str,
2445        /,
2446        loadout_index: int,
2447        character_id: int,
2448        membership_type: enums.MembershipType | int,
2449        *,
2450        color_hash: int | None = None,
2451        icon_hash: int | None = None,
2452        name_hash: int | None = None,
2453    ) -> None:
2454        response = await self._request(
2455            _POST,
2456            "Destiny2/Actions/Loadouts/UpdateLoadoutIdentifiers/",
2457            auth=access_token,
2458            json={
2459                "colorHash": color_hash,
2460                "iconHash": icon_hash,
2461                "nameHash": name_hash,
2462                "loadoutIndex": loadout_index,
2463                "characterId": character_id,
2464                "membershipType": int(membership_type),
2465            },
2466        )
2467        assert isinstance(response, int)

Update the loadout. Color, Icon and Name.

This operation requires MoveEquipDestinyItems OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • loadout_index (int): The index of the loadout to use.
  • character_id (int): The character ID to equip the loadout to.
  • membership_type (aiobungie.MembershipType | int): The membership type of the account.
Other Parameters
  • color_hash (int | None): The new color hash of the loadout to update.
  • icon_hash (int | None): The new icon hash of the loadout to update.
  • name_hash (int | None): The new name hash of the loadout to update.
async def clear_loadout( self, access_token: 'str', /, loadout_index: 'int', character_id: 'int', membership_type: 'enums.MembershipType | int') -> 'None':
2469    async def clear_loadout(
2470        self,
2471        access_token: str,
2472        /,
2473        loadout_index: int,
2474        character_id: int,
2475        membership_type: enums.MembershipType | int,
2476    ) -> None:
2477        response = await self._request(
2478            _POST,
2479            "Destiny2/Actions/Loadouts/ClearLoadout/",
2480            json={
2481                "loadoutIndex": loadout_index,
2482                "characterId": character_id,
2483                "membership_type": int(membership_type),
2484            },
2485            auth=access_token,
2486        )
2487        assert isinstance(response, int)

Clear the identifiers and items of a loadout.

This operation requires MoveEquipDestinyItems OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account.
  • loadout_index (int): The index of the loadout to use.
  • character_id (int): The character ID to equip the loadout to.
  • membership_type (aiobungie.MembershipType | int): The membership type of the account.
async def force_drops_repair(self, access_token: 'str', /) -> 'bool':
2489    async def force_drops_repair(self, access_token: str, /) -> bool:
2490        response = await self._request(
2491            _POST, "Tokens/Partner/ForceDropsRepair/", auth=access_token
2492        )
2493        assert isinstance(response, bool)
2494        return response

Twitch Drops self-repair function - scans twitch for drops not marked as fulfilled and resyncs them.

This operation requires PartnerOfferGrant OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account that will be used to make the request with.
Returns
  • bool: The nature of this response is a boolean.
async def claim_partner_offer( self, access_token: 'str', /, *, offer_id: 'str', bungie_membership_id: 'int', transaction_id: 'str') -> 'bool':
2496    async def claim_partner_offer(
2497        self,
2498        access_token: str,
2499        /,
2500        *,
2501        offer_id: str,
2502        bungie_membership_id: int,
2503        transaction_id: str,
2504    ) -> bool:
2505        response = await self._request(
2506            _POST,
2507            "Tokens/Partner/ClaimOffer/",
2508            json={
2509                "PartnerOfferId": offer_id,
2510                "BungieNetMembershipId": bungie_membership_id,
2511                "TransactionId": transaction_id,
2512            },
2513            auth=access_token,
2514        )
2515        assert isinstance(response, bool)
2516        return response

Claim a partner offer as the authenticated user.

This operation requires PartnerOfferGrant OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account that will be used to make the request with.
  • offer_id (str): The partner offer ID
  • bungie_membership_id (int): The associated Bungie.net membership ID
  • transaction_id (str): The transaction ID
Returns
  • bool: The nature of this response is a boolean.
async def fetch_bungie_rewards_for_user( self, access_token: 'str', /, membership_id: 'int') -> 'typedefs.JSONObject':
2518    async def fetch_bungie_rewards_for_user(
2519        self, access_token: str, /, membership_id: int
2520    ) -> typedefs.JSONObject:
2521        response = await self._request(
2522            _GET,
2523            f"Tokens/Rewards/GetRewardsForUser/{membership_id}/",
2524            auth=access_token,
2525        )
2526        assert isinstance(response, dict)
2527        return response

Returns the bungie rewards for the targeted user.

This operation requires ReadAndApplyTokens OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account that will be used to make the request with.
  • membership_id (int): The associated membership ID to fetch the rewards for.
Returns
async def fetch_bungie_rewards_for_platform( self, access_token: 'str', /, membership_id: 'int', membership_type: 'enums.MembershipType | int') -> 'typedefs.JSONObject':
2529    async def fetch_bungie_rewards_for_platform(
2530        self,
2531        access_token: str,
2532        /,
2533        membership_id: int,
2534        membership_type: enums.MembershipType | int,
2535    ) -> typedefs.JSONObject:
2536        response = await self._request(
2537            _GET,
2538            f"Tokens/Rewards/GetRewardsForPlatformUser/{membership_id}/{int(membership_type)}",
2539            auth=access_token,
2540        )
2541        assert isinstance(response, dict)
2542        return response

Returns the bungie rewards for the targeted user and membership.

This operation requires ReadAndApplyTokens OAuth2 scope.

Parameters
  • access_token (str): The bearer access token associated with the bungie account that will be used to make the request with.
  • membership_id (int): The associated membership ID to fetch the rewards for.
  • membership_type (aiobungie.MembershipType | int): The associated membership type for the user.
Returns
async def fetch_bungie_rewards(self) -> 'typedefs.JSONObject':
2544    async def fetch_bungie_rewards(self) -> typedefs.JSONObject:
2545        response = await self._request(_GET, "Tokens/Rewards/BungieRewards/")
2546        assert isinstance(response, dict)
2547        return response

Returns a list of the current bungie rewards.

Returns
async def fetch_fireteam_listing(self, listing_id: 'int') -> 'typedefs.JSONObject':
2549    async def fetch_fireteam_listing(self, listing_id: int) -> typedefs.JSONObject:
2550        response = await self._request(_GET, f"FireteamFinder/Listing/{listing_id}/")
2551        assert isinstance(response, dict)
2552        return response
class RESTPool:
202class RESTPool:
203    """a Pool of `RESTClient` instances that shares the same TCP client connection.
204
205    This allows you to acquire instances of `RESTClient`s from single settings and credentials.
206
207    Example
208    -------
209    ```py
210    import aiobungie
211    import asyncio
212
213    pool = aiobungie.RESTPool("token")
214
215    async def get() -> None:
216        await pool.start()
217
218        async with pool.acquire() as client:
219            await client.fetch_character(...)
220
221        await pool.stop()
222
223    asyncio.run(get())
224    ```
225
226    Parameters
227    ----------
228    token : `str`
229        A valid application token from Bungie's developer portal.
230
231    Other Parameters
232    ----------------
233    client_secret : `str | None`
234        An optional application client secret,
235        This is only needed if you're fetching OAuth2 tokens with this client.
236    client_id : `int | None`
237        An optional application client id,
238        This is only needed if you're fetching OAuth2 tokens with this client.
239    settings: `aiobungie.builders.Settings | None`
240        The client settings to use, if `None` the default will be used.
241    max_retries : `int`
242        The max retries number to retry if the request hit a `5xx` status code.
243    debug : `bool | str`
244        Whether to enable logging responses or not.
245
246    Logging Levels
247    --------------
248    * `False`: This will disable logging.
249    * `True`: This will set the level to `DEBUG` and enable logging minimal information.
250    Like the response status, route, taken time and so on.
251    * `"TRACE" | aiobungie.TRACE`: This will log the response headers along with the minimal information.
252    """
253
254    __slots__ = (
255        "_token",
256        "_max_retries",
257        "_client_secret",
258        "_client_id",
259        "_metadata",
260        "_enable_debug",
261        "_client_session",
262        "_loads",
263        "_dumps",
264        "_settings",
265    )
266
267    # Looks like mypy doesn't like this.
268    if typing.TYPE_CHECKING:
269        _enable_debug: typing.Literal["TRACE"] | bool | int
270
271    def __init__(
272        self,
273        token: str,
274        /,
275        *,
276        client_secret: str | None = None,
277        client_id: int | None = None,
278        settings: builders.Settings | None = None,
279        dumps: typedefs.Dumps = helpers.dumps,
280        loads: typedefs.Loads = helpers.loads,
281        max_retries: int = 4,
282        debug: typing.Literal["TRACE"] | bool | int = False,
283    ) -> None:
284        self._client_secret = client_secret
285        self._client_id = client_id
286        self._token = token
287        self._max_retries = max_retries
288        self._metadata: collections.MutableMapping[typing.Any, typing.Any] = {}
289        self._enable_debug = debug
290        self._client_session: aiohttp.ClientSession | None = None
291        self._loads = loads
292        self._dumps = dumps
293        self._settings = settings or builders.Settings()
294
295    @property
296    def client_id(self) -> int | None:
297        """Return the client id of this REST client if provided, Otherwise None."""
298        return self._client_id
299
300    @property
301    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
302        """A general-purpose mutable mapping you can use to store data.
303
304        This mapping can be accessed from any process that has a reference to this pool.
305        """
306        return self._metadata
307
308    @property
309    def settings(self) -> builders.Settings:
310        """Internal client settings used within the HTTP client session."""
311        return self._settings
312
313    @typing.overload
314    def build_oauth2_url(self, client_id: int) -> builders.OAuthURL: ...
315
316    @typing.overload
317    def build_oauth2_url(self) -> builders.OAuthURL | None: ...
318
319    @typing.final
320    def build_oauth2_url(
321        self, client_id: int | None = None
322    ) -> builders.OAuthURL | None:
323        """Construct a new `OAuthURL` url object.
324
325        You can get the complete string representation of the url by calling `.compile()` on it.
326
327        Parameters
328        ----------
329        client_id : `int | None`
330            An optional client id to provide, If left `None` it will roll back to the id passed
331            to the `RESTClient`, If both is `None` this method will return `None`.
332
333        Returns
334        -------
335        `aiobungie.builders.OAuthURL | None`
336            * If `client_id` was provided as a parameter, It guarantees to return a complete `OAuthURL` object
337            * If `client_id` is set to `aiobungie.RESTClient` will be.
338            * If both are `None` this method will return `None.
339        """
340        client_id = client_id or self._client_id
341        if client_id is None:
342            return None
343
344        return builders.OAuthURL(client_id=client_id)
345
346    async def start(self) -> None:
347        """Start the TCP connection of this client pool.
348
349        This will raise `RuntimeError` if the connection has already been started.
350
351        Example
352        -------
353        ```py
354        pool = aiobungie.RESTPool(...)
355
356        async def run() -> None:
357            await pool.start()
358            async with pool.acquire() as client:
359                # use client
360
361        async def stop(self) -> None:
362            await pool.close()
363        ```
364        """
365        if self._client_session is not None:
366            raise RuntimeError("<RESTPool> has already been started.") from None
367
368        self._client_session = aiohttp.ClientSession(
369            connector=aiohttp.TCPConnector(
370                use_dns_cache=self._settings.use_dns_cache,
371                ttl_dns_cache=self._settings.ttl_dns_cache,
372                ssl_context=self._settings.ssl_context,
373                ssl=self._settings.ssl,
374            ),
375            connector_owner=True,
376            raise_for_status=False,
377            timeout=self._settings.http_timeout,
378            trust_env=self._settings.trust_env,
379            headers=self._settings.headers,
380        )
381
382    async def stop(self) -> None:
383        """Stop the TCP connection of this client pool.
384
385        This will raise `RuntimeError` if the connection has already been closed.
386
387        Example
388        -------
389        ```py
390        pool = aiobungie.RESTPool(...)
391
392        async def run() -> None:
393            await pool.start()
394            async with pool.acquire() as client:
395                # use client
396
397        async def stop(self) -> None:
398            await pool.close()
399        ```
400        """
401        if self._client_session is None:
402            raise RuntimeError("<RESTPool> is already stopped.")
403
404        await self._client_session.close()
405        self._client_session = None
406
407    @typing.final
408    def acquire(self) -> RESTClient:
409        """Acquires a new `RESTClient` instance from this pool.
410
411        Returns
412        -------
413        `RESTClient`
414            An instance of a `RESTClient`.
415        """
416        return RESTClient(
417            self._token,
418            client_secret=self._client_secret,
419            client_id=self._client_id,
420            loads=self._loads,
421            dumps=self._dumps,
422            max_retries=self._max_retries,
423            debug=self._enable_debug,
424            client_session=self._client_session,
425            owned_client=False,
426            settings=self._settings,
427        )

a Pool of RESTClient instances that shares the same TCP client connection.

This allows you to acquire instances of RESTClients from single settings and credentials.

Example
import aiobungie
import asyncio

pool = aiobungie.RESTPool("token")

async def get() -> None:
    await pool.start()

    async with pool.acquire() as client:
        await client.fetch_character(...)

    await pool.stop()

asyncio.run(get())
Parameters
  • token (str): A valid application token from Bungie's developer portal.
Other Parameters
  • client_secret (str | None): An optional application client secret, This is only needed if you're fetching OAuth2 tokens with this client.
  • client_id (int | None): An optional application client id, This is only needed if you're fetching OAuth2 tokens with this client.
  • settings (aiobungie.builders.Settings | None): The client settings to use, if None the default will be used.
  • max_retries (int): The max retries number to retry if the request hit a 5xx status code.
  • debug (bool | str): Whether to enable logging responses or not.
Logging Levels
  • False: This will disable logging.
  • True: This will set the level to DEBUG and enable logging minimal information. Like the response status, route, taken time and so on.
  • "TRACE" | aiobungie.TRACE: This will log the response headers along with the minimal information.
RESTPool( token: 'str', /, *, client_secret: 'str | None' = None, client_id: 'int | None' = None, settings: 'builders.Settings | None' = None, dumps: 'typedefs.Dumps' = <function dumps>, loads: 'typedefs.Loads' = <function loads>, max_retries: 'int' = 4, debug: "typing.Literal['TRACE'] | bool | int" = False)
271    def __init__(
272        self,
273        token: str,
274        /,
275        *,
276        client_secret: str | None = None,
277        client_id: int | None = None,
278        settings: builders.Settings | None = None,
279        dumps: typedefs.Dumps = helpers.dumps,
280        loads: typedefs.Loads = helpers.loads,
281        max_retries: int = 4,
282        debug: typing.Literal["TRACE"] | bool | int = False,
283    ) -> None:
284        self._client_secret = client_secret
285        self._client_id = client_id
286        self._token = token
287        self._max_retries = max_retries
288        self._metadata: collections.MutableMapping[typing.Any, typing.Any] = {}
289        self._enable_debug = debug
290        self._client_session: aiohttp.ClientSession | None = None
291        self._loads = loads
292        self._dumps = dumps
293        self._settings = settings or builders.Settings()
client_id: 'int | None'
295    @property
296    def client_id(self) -> int | None:
297        """Return the client id of this REST client if provided, Otherwise None."""
298        return self._client_id

Return the client id of this REST client if provided, Otherwise None.

metadata: 'collections.MutableMapping[typing.Any, typing.Any]'
300    @property
301    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
302        """A general-purpose mutable mapping you can use to store data.
303
304        This mapping can be accessed from any process that has a reference to this pool.
305        """
306        return self._metadata

A general-purpose mutable mapping you can use to store data.

This mapping can be accessed from any process that has a reference to this pool.

settings: 'builders.Settings'
308    @property
309    def settings(self) -> builders.Settings:
310        """Internal client settings used within the HTTP client session."""
311        return self._settings

Internal client settings used within the HTTP client session.

@typing.final
def build_oauth2_url(self, client_id: 'int | None' = None) -> 'builders.OAuthURL | None':
319    @typing.final
320    def build_oauth2_url(
321        self, client_id: int | None = None
322    ) -> builders.OAuthURL | None:
323        """Construct a new `OAuthURL` url object.
324
325        You can get the complete string representation of the url by calling `.compile()` on it.
326
327        Parameters
328        ----------
329        client_id : `int | None`
330            An optional client id to provide, If left `None` it will roll back to the id passed
331            to the `RESTClient`, If both is `None` this method will return `None`.
332
333        Returns
334        -------
335        `aiobungie.builders.OAuthURL | None`
336            * If `client_id` was provided as a parameter, It guarantees to return a complete `OAuthURL` object
337            * If `client_id` is set to `aiobungie.RESTClient` will be.
338            * If both are `None` this method will return `None.
339        """
340        client_id = client_id or self._client_id
341        if client_id is None:
342            return None
343
344        return builders.OAuthURL(client_id=client_id)

Construct a new OAuthURL url object.

You can get the complete string representation of the url by calling .compile() on it.

Parameters
  • client_id (int | None): An optional client id to provide, If left None it will roll back to the id passed to the RESTClient, If both is None this method will return None.
Returns
async def start(self) -> 'None':
346    async def start(self) -> None:
347        """Start the TCP connection of this client pool.
348
349        This will raise `RuntimeError` if the connection has already been started.
350
351        Example
352        -------
353        ```py
354        pool = aiobungie.RESTPool(...)
355
356        async def run() -> None:
357            await pool.start()
358            async with pool.acquire() as client:
359                # use client
360
361        async def stop(self) -> None:
362            await pool.close()
363        ```
364        """
365        if self._client_session is not None:
366            raise RuntimeError("<RESTPool> has already been started.") from None
367
368        self._client_session = aiohttp.ClientSession(
369            connector=aiohttp.TCPConnector(
370                use_dns_cache=self._settings.use_dns_cache,
371                ttl_dns_cache=self._settings.ttl_dns_cache,
372                ssl_context=self._settings.ssl_context,
373                ssl=self._settings.ssl,
374            ),
375            connector_owner=True,
376            raise_for_status=False,
377            timeout=self._settings.http_timeout,
378            trust_env=self._settings.trust_env,
379            headers=self._settings.headers,
380        )

Start the TCP connection of this client pool.

This will raise RuntimeError if the connection has already been started.

Example
pool = aiobungie.RESTPool(...)

async def run() -> None:
    await pool.start()
    async with pool.acquire() as client:
        # use client

async def stop(self) -> None:
    await pool.close()
async def stop(self) -> 'None':
382    async def stop(self) -> None:
383        """Stop the TCP connection of this client pool.
384
385        This will raise `RuntimeError` if the connection has already been closed.
386
387        Example
388        -------
389        ```py
390        pool = aiobungie.RESTPool(...)
391
392        async def run() -> None:
393            await pool.start()
394            async with pool.acquire() as client:
395                # use client
396
397        async def stop(self) -> None:
398            await pool.close()
399        ```
400        """
401        if self._client_session is None:
402            raise RuntimeError("<RESTPool> is already stopped.")
403
404        await self._client_session.close()
405        self._client_session = None

Stop the TCP connection of this client pool.

This will raise RuntimeError if the connection has already been closed.

Example
pool = aiobungie.RESTPool(...)

async def run() -> None:
    await pool.start()
    async with pool.acquire() as client:
        # use client

async def stop(self) -> None:
    await pool.close()
@typing.final
def acquire(self) -> 'RESTClient':
407    @typing.final
408    def acquire(self) -> RESTClient:
409        """Acquires a new `RESTClient` instance from this pool.
410
411        Returns
412        -------
413        `RESTClient`
414            An instance of a `RESTClient`.
415        """
416        return RESTClient(
417            self._token,
418            client_secret=self._client_secret,
419            client_id=self._client_id,
420            loads=self._loads,
421            dumps=self._dumps,
422            max_retries=self._max_retries,
423            debug=self._enable_debug,
424            client_session=self._client_session,
425            owned_client=False,
426            settings=self._settings,
427        )

Acquires a new RESTClient instance from this pool.

Returns
@typing.final
class Race(builtins.int, aiobungie.Enum):
488@typing.final
489class Race(int, Enum):
490    """An Enum for Destiny races."""
491
492    HUMAN = 0
493    AWOKEN = 1
494    EXO = 2
495    UNKNOWN = 3

An Enum for Destiny races.

HUMAN = <Race.HUMAN: 0>
AWOKEN = <Race.AWOKEN: 1>
EXO = <Race.EXO: 2>
UNKNOWN = <Race.UNKNOWN: 3>
Inherited Members
Enum
name
value
@typing.final
class Raid(builtins.int, aiobungie.Enum):
134@typing.final
135class Raid(int, Enum):
136    """An Enum for all available raids in Destiny 2."""
137
138    DSC = 910380154
139    """Deep Stone Crypt"""
140
141    LW = 2122313384
142    """Last Wish"""
143
144    VOG = 3881495763
145    """Normal Valut of Glass"""
146
147    GOS = 3458480158
148    """Garden Of Salvation"""

An Enum for all available raids in Destiny 2.

DSC = <Raid.DSC: 910380154>

Deep Stone Crypt

LW = <Raid.LW: 2122313384>

Last Wish

VOG = <Raid.VOG: 3881495763>

Normal Valut of Glass

GOS = <Raid.GOS: 3458480158>

Garden Of Salvation

Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class RateLimitedError(aiobungie.HTTPError):
258@attrs.define(auto_exc=True)
259class RateLimitedError(HTTPError):
260    """Raised when too many request status code is returned."""
261
262    http_status: http.HTTPStatus = attrs.field(
263        default=http.HTTPStatus.TOO_MANY_REQUESTS, init=False
264    )
265    """The request response http status."""
266
267    url: typedefs.StrOrURL
268    """The URL/endpoint caused this error."""
269
270    body: typing.Any
271    """The response body."""
272
273    retry_after: float = attrs.field(default=0.0)
274    """The amount of seconds you need to wait before retrying to requests."""
275
276    message: str = attrs.field(init=False)
277    """A Bungie human readable message describes the cause of the error."""
278
279    # Type Ignore: attrs provide a `.default` setter on its attribs to allow
280    # changing the default value.
281    @message.default  # pyright: ignore
282    def _(self) -> str:
283        return f"You're ratelimited for {self.retry_after}, Endpoint: {self.url}. Slow down!"
284
285    def __str__(self) -> str:
286        return self.message

Raised when too many request status code is returned.

RateLimitedError( url: 'typedefs.StrOrURL', body: 'typing.Any', retry_after: 'float' = 0.0)
17def __init__(self, url, body, retry_after=attr_dict['retry_after'].default):
18    self.http_status = attr_dict['http_status'].default
19    self.url = url
20    self.body = body
21    self.retry_after = retry_after
22    self.message = __attr_factory_message(self)
23    BaseException.__init__(self, self.url,self.body,self.retry_after)

Method generated by attrs for class RateLimitedError.

http_status: 'http.HTTPStatus'

The request response http status.

url: 'typedefs.StrOrURL'

The URL/endpoint caused this error.

body: 'typing.Any'

The response body.

retry_after: 'float'

The amount of seconds you need to wait before retrying to requests.

message: 'str'

A Bungie human readable message describes the cause of the error.

@typing.final
class RecordState(aiobungie.Flag):
46@typing.final
47class RecordState(enums.Flag):
48    """An enum for records component states."""
49
50    NONE = 0
51    REDEEMED = 1 << 0
52    UNAVAILABLE = 1 << 1
53    OBJECTIVE_NOT_COMPLETED = 1 << 2
54    OBSCURED = 1 << 3
55    INVISIBLE = 1 << 4
56    ENTITLEMENT_UNOWNED = 1 << 5
57    CAN_EQUIP_TITLE = 1 << 6

An enum for records component states.

NONE = <RecordState.NONE: 0>
REDEEMED = <RecordState.REDEEMED: 1>
UNAVAILABLE = <RecordState.UNAVAILABLE: 2>
OBJECTIVE_NOT_COMPLETED = <RecordState.OBJECTIVE_NOT_COMPLETED: 4>
OBSCURED = <RecordState.OBSCURED: 8>
INVISIBLE = <RecordState.INVISIBLE: 16>
ENTITLEMENT_UNOWNED = <RecordState.ENTITLEMENT_UNOWNED: 32>
CAN_EQUIP_TITLE = <RecordState.CAN_EQUIP_TITLE: 64>
Inherited Members
Flag
name
value
@typing.final
class Relationship(builtins.int, aiobungie.Enum):
683@typing.final
684class Relationship(int, Enum):
685    """An enum for bungie friends relationship types."""
686
687    UNKNOWN = 0
688    FRIEND = 1
689    INCOMING_REQUEST = 2
690    OUTGOING_REQUEST = 3

An enum for bungie friends relationship types.

UNKNOWN = <Relationship.UNKNOWN: 0>
FRIEND = <Relationship.FRIEND: 1>
INCOMING_REQUEST = <Relationship.INCOMING_REQUEST: 2>
OUTGOING_REQUEST = <Relationship.OUTGOING_REQUEST: 3>
Inherited Members
Enum
name
value
@attrs.define(auto_exc=True)
class ResponseError(aiobungie.HTTPException):
253@attrs.define(auto_exc=True)
254class ResponseError(HTTPException):
255    """Exception for other HTTP response errors."""

Exception for other HTTP response errors.

ResponseError( *, error_code: 'int', http_status: 'http.HTTPStatus', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, http_status, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.http_status = http_status
20    self.throttle_seconds = throttle_seconds
21    self.url = url
22    self.body = body
23    self.headers = headers
24    self.message = message
25    self.error_status = error_status
26    self.message_data = message_data
27    BaseException.__init__(self, self.error_code,self.http_status,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class ResponseError.

@typing.final
class Stat(builtins.int, aiobungie.Enum):
510@typing.final
511class Stat(int, Enum):
512    """An Enum for Destiny 2 character stats."""
513
514    NONE = 0
515    MOBILITY = 2996146975
516    RESILIENCE = 392767087
517    RECOVERY = 1943323491
518    DISCIPLINE = 1735777505
519    INTELLECT = 144602215
520    STRENGTH = 4244567218
521    LIGHT_POWER = 1935470627

An Enum for Destiny 2 character stats.

NONE = <Stat.NONE: 0>
MOBILITY = <Stat.MOBILITY: 2996146975>
RESILIENCE = <Stat.RESILIENCE: 392767087>
RECOVERY = <Stat.RECOVERY: 1943323491>
DISCIPLINE = <Stat.DISCIPLINE: 1735777505>
INTELLECT = <Stat.INTELLECT: 144602215>
STRENGTH = <Stat.STRENGTH: 4244567218>
LIGHT_POWER = <Stat.LIGHT_POWER: 1935470627>
Inherited Members
Enum
name
value
TRACE = 5
@typing.final
class TierType(builtins.int, aiobungie.Enum):
625@typing.final
626class TierType(int, Enum):
627    """An enum for a Destiny 2 item tier type."""
628
629    UNKNOWN = 0
630    CURRENCY = 1
631    BASIC = 2
632    COMMON = 3
633    RARE = 4
634    SUPERIOR = 5
635    EXOTIC = 6

An enum for a Destiny 2 item tier type.

UNKNOWN = <TierType.UNKNOWN: 0>
CURRENCY = <TierType.CURRENCY: 1>
BASIC = <TierType.BASIC: 2>
COMMON = <TierType.COMMON: 3>
RARE = <TierType.RARE: 4>
SUPERIOR = <TierType.SUPERIOR: 5>
EXOTIC = <TierType.EXOTIC: 6>
Inherited Members
Enum
name
value
@typing.final
class TransferStatus(aiobungie.Flag):
735@typing.final
736class TransferStatus(Flag):
737    """An enum for items transfer statuses."""
738
739    CAN_TRANSFER = 0
740    """The item can be transferred."""
741    IS_EQUIPPED = 1 << 0
742    """You can't transfer since the item is equipped."""
743    NOT_TRASNFERRABLE = 1 << 1
744    """This item can not be transferred."""
745    COULD_BE_TRANSFERRED = 1 << 2
746    """You can transfer the item. But the place you're trying to put it at has no space for it."""

An enum for items transfer statuses.

CAN_TRANSFER = <TransferStatus.CAN_TRANSFER: 0>

The item can be transferred.

IS_EQUIPPED = <TransferStatus.IS_EQUIPPED: 1>

You can't transfer since the item is equipped.

NOT_TRASNFERRABLE = <TransferStatus.NOT_TRASNFERRABLE: 2>

This item can not be transferred.

COULD_BE_TRANSFERRED = <TransferStatus.COULD_BE_TRANSFERRED: 4>

You can transfer the item. But the place you're trying to put it at has no space for it.

Inherited Members
Flag
name
value
@attrs.define(auto_exc=True)
class Unauthorized(aiobungie.HTTPException):
162@attrs.define(auto_exc=True)
163class Unauthorized(HTTPException):
164    """An exception that's raised when trying to make unauthorized call to a resource and it returns 404."""
165
166    http_status: http.HTTPStatus = attrs.field(
167        default=http.HTTPStatus.UNAUTHORIZED, init=False
168    )

An exception that's raised when trying to make unauthorized call to a resource and it returns 404.

Unauthorized( *, error_code: 'int', throttle_seconds: 'int', url: 'typedefs.StrOrURL | None', body: 'typing.Any', headers: 'multidict.CIMultiDictProxy[str]', message: 'str', error_status: 'str', message_data: 'dict[str, str]')
17def __init__(self, *, error_code, throttle_seconds, url, body, headers, message, error_status, message_data):
18    self.error_code = error_code
19    self.throttle_seconds = throttle_seconds
20    self.url = url
21    self.body = body
22    self.headers = headers
23    self.message = message
24    self.error_status = error_status
25    self.message_data = message_data
26    self.http_status = attr_dict['http_status'].default
27    BaseException.__init__(self, self.error_code,self.throttle_seconds,self.url,self.body,self.headers,self.message,self.error_status,self.message_data)

Method generated by attrs for class Unauthorized.

http_status: 'http.HTTPStatus'

The request response http status.

@typing.final
class ValueUIStyle(builtins.int, aiobungie.Enum):
72@typing.final
73class ValueUIStyle(int, enums.Enum):
74    AUTOMATIC = 0
75    FRACTION = 1
76    CHECK_BOX = 2
77    PERCENTAGE = 3
78    DATETIME = 4
79    FRACTION_FLOAT = 5
80    INTEGER = 6
81    TIME_DURATION = 7
82    HIDDEN = 8
83    MULTIPLIER = 9
84    GREEN_PIPS = 10
85    RED_PIPS = 11
86    EXPLICIT_PERCENTAGE = 12
87    RAW_FLOAT = 13
88    LEVEL_AND_REWARD = 14

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

>>> int('0b100', base=0)
4
AUTOMATIC = <ValueUIStyle.AUTOMATIC: 0>
FRACTION = <ValueUIStyle.FRACTION: 1>
CHECK_BOX = <ValueUIStyle.CHECK_BOX: 2>
PERCENTAGE = <ValueUIStyle.PERCENTAGE: 3>
DATETIME = <ValueUIStyle.DATETIME: 4>
FRACTION_FLOAT = <ValueUIStyle.FRACTION_FLOAT: 5>
INTEGER = <ValueUIStyle.INTEGER: 6>
TIME_DURATION = <ValueUIStyle.TIME_DURATION: 7>
HIDDEN = <ValueUIStyle.HIDDEN: 8>
MULTIPLIER = <ValueUIStyle.MULTIPLIER: 9>
GREEN_PIPS = <ValueUIStyle.GREEN_PIPS: 10>
RED_PIPS = <ValueUIStyle.RED_PIPS: 11>
EXPLICIT_PERCENTAGE = <ValueUIStyle.EXPLICIT_PERCENTAGE: 12>
RAW_FLOAT = <ValueUIStyle.RAW_FLOAT: 13>
LEVEL_AND_REWARD = <ValueUIStyle.LEVEL_AND_REWARD: 14>
Inherited Members
Enum
name
value
@typing.final
class Vendor(builtins.int, aiobungie.Enum):
231@typing.final
232class Vendor(int, Enum):
233    """An Enum for all available vendors in Destiny 2."""
234
235    ZAVALA = 69482069
236    XUR = 2190858386
237    BANSHE = 672118013
238    SPIDER = 863940356
239    SHAXX = 3603221665
240    KADI = 529635856
241    """Postmaster exo."""
242    YUNA = 1796504621
243    """Asia servers only."""
244    EVERVERSE = 3361454721
245    AMANDA = 460529231
246    """Amanda holiday"""
247    CROW = 3611983588
248    HAWTHORNE = 3347378076
249    ADA1 = 350061650
250    DRIFTER = 248695599
251    IKORA = 1976548992
252    SAINT = 765357505
253    """Saint-14"""
254    ERIS_MORN = 1616085565
255    SHAW_HAWN = 1816541247
256    """COSMODROME Guy"""
257    VARIKS = 2531198101

An Enum for all available vendors in Destiny 2.

ZAVALA = <Vendor.ZAVALA: 69482069>
XUR = <Vendor.XUR: 2190858386>
BANSHE = <Vendor.BANSHE: 672118013>
SPIDER = <Vendor.SPIDER: 863940356>
SHAXX = <Vendor.SHAXX: 3603221665>
KADI = <Vendor.KADI: 529635856>

Postmaster exo.

YUNA = <Vendor.YUNA: 1796504621>

Asia servers only.

EVERVERSE = <Vendor.EVERVERSE: 3361454721>
AMANDA = <Vendor.AMANDA: 460529231>

Amanda holiday

CROW = <Vendor.CROW: 3611983588>
HAWTHORNE = <Vendor.HAWTHORNE: 3347378076>
ADA1 = <Vendor.ADA1: 350061650>
DRIFTER = <Vendor.DRIFTER: 248695599>
IKORA = <Vendor.IKORA: 1976548992>
SAINT = <Vendor.SAINT: 765357505>

Saint-14

ERIS_MORN = <Vendor.ERIS_MORN: 1616085565>
SHAW_HAWN = <Vendor.SHAW_HAWN: 1816541247>

COSMODROME Guy

VARIKS = <Vendor.VARIKS: 2531198101>
Inherited Members
Enum
name
value
@typing.final
class WeaponType(builtins.int, aiobungie.Enum):
524@typing.final
525class WeaponType(int, Enum):
526    """Enums for The three Destiny Weapon Types"""
527
528    NONE = 0
529    KINETIC = 1498876634
530    ENERGY = 2465295065
531    POWER = 953998645

Enums for The three Destiny Weapon Types

NONE = <WeaponType.NONE: 0>
KINETIC = <WeaponType.KINETIC: 1498876634>
ENERGY = <WeaponType.ENERGY: 2465295065>
POWER = <WeaponType.POWER: 953998645>
Inherited Members
Enum
name
value
annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216)
async def panic(response: 'aiohttp.ClientResponse') -> 'HTTPError':
289async def panic(response: aiohttp.ClientResponse) -> HTTPError:
290    """Immediately raise an exception based on the response."""
291
292    # Bungie get funky and return HTML instead of JSON when making an authorized
293    # request with a dummy access token. We could technically read the page content
294    # but that's Bungie's fault for not returning a JSON response.
295    if response.content_type != "application/json":
296        raise HTTPError(
297            message=f"Expected JSON response, Got {response.content_type}, "
298            f"{response.real_url.human_repr()}",
299            http_status=http.HTTPStatus(response.status),
300        )
301
302    body: collections.Mapping[str, typing.Any] = helpers.loads(await response.read())  # type: ignore
303    message: str = body.get("Message", "UNDEFINED_MESSAGE")
304    error_status: str = body.get("ErrorStatus", "UNDEFINED_ERROR_STATUS")
305    message_data: dict[str, str] = body.get("MessageData", {})
306    throttle_seconds: int = body.get("ThrottleSeconds", 0)
307    error_code: int = body.get("ErrorCode", 0)
308
309    # Standard HTTP status.
310    match response.status:
311        case http.HTTPStatus.NOT_FOUND:
312            return NotFound(
313                message=message,
314                error_code=error_code,
315                throttle_seconds=throttle_seconds,
316                url=str(response.real_url),
317                body=body,
318                headers=response.headers,
319                error_status=error_status,
320                message_data=message_data,
321            )
322
323        case http.HTTPStatus.FORBIDDEN:
324            return Forbidden(
325                message=message,
326                error_code=error_code,
327                throttle_seconds=throttle_seconds,
328                url=str(response.real_url),
329                body=body,
330                headers=response.headers,
331                error_status=error_status,
332                message_data=message_data,
333            )
334
335        case http.HTTPStatus.UNAUTHORIZED:
336            return Unauthorized(
337                message=message,
338                error_code=error_code,
339                throttle_seconds=throttle_seconds,
340                url=str(response.real_url),
341                body=body,
342                headers=response.headers,
343                error_status=error_status,
344                message_data=message_data,
345            )
346
347        case http.HTTPStatus.BAD_REQUEST:
348            # Membership needs to be alone.
349            if error_status == "InvalidParameters":
350                return MembershipTypeError(
351                    message=message,
352                    body=body,
353                    headers=response.headers,
354                    url=str(response.url),
355                    membership_type=message_data["membershipType"],
356                    required_membership=message_data["membershipInfo.membershipType"],
357                    membership_id=int(message_data["membershipId"]),
358                )
359            return BadRequest(
360                message=message,
361                body=body,
362                headers=response.headers,
363                url=str(response.url),
364            )
365        case _:
366            status = http.HTTPStatus(response.status)
367
368            if 400 <= status < 500:
369                return ResponseError(
370                    message=message,
371                    error_code=error_code,
372                    throttle_seconds=throttle_seconds,
373                    url=str(response.real_url),
374                    body=body,
375                    headers=response.headers,
376                    error_status=error_status,
377                    message_data=message_data,
378                    http_status=status,
379                )
380
381            # Need to self handle ~5xx errors
382            elif 500 <= status < 600:
383                # No API key or method requires OAuth2 most likely.
384                if error_status in {
385                    "ApiKeyMissingFromRequest",
386                    "WebAuthRequired",
387                    "ApiInvalidOrExpiredKey",
388                    "AuthenticationInvalid",
389                    "AuthorizationCodeInvalid",
390                }:
391                    return Unauthorized(
392                        message=message,
393                        error_code=error_code,
394                        throttle_seconds=throttle_seconds,
395                        url=str(response.real_url),
396                        body=body,
397                        headers=response.headers,
398                        error_status=error_status,
399                        message_data=message_data,
400                    )
401
402                # Anything contains not found.
403                elif (
404                    "NotFound" in error_status
405                    or error_status == "UserCannotFindRequestedUser"
406                ):
407                    return NotFound(
408                        message=message,
409                        error_code=error_code,
410                        throttle_seconds=throttle_seconds,
411                        url=str(response.real_url),
412                        body=body,
413                        headers=response.headers,
414                        error_status=error_status,
415                        message_data=message_data,
416                    )
417
418                # Other 5xx errors.
419                else:
420                    return InternalServerError(
421                        message=message,
422                        error_code=error_code,
423                        throttle_seconds=throttle_seconds,
424                        url=str(response.real_url),
425                        body=body,
426                        headers=response.headers,
427                        error_status=error_status,
428                        message_data=message_data,
429                        http_status=status,
430                    )
431            # Something else.
432            else:
433                return HTTPException(
434                    message=message,
435                    error_code=error_code,
436                    throttle_seconds=throttle_seconds,
437                    url=str(response.real_url),
438                    body=body,
439                    headers=response.headers,
440                    error_status=error_status,
441                    message_data=message_data,
442                    http_status=status,
443                )

Immediately raise an exception based on the response.

def stringify_headers(headers: 'collections.Mapping[str, typing.Any]') -> 'str':
452def stringify_headers(headers: collections.Mapping[str, typing.Any]) -> str:
453    if not headers:
454        return ""
455
456    return (
457        "{ \n"
458        + "\n".join(
459            f"{f'   {key}'}: {value}"
460            if key not in _SENSITIVE_KEYS
461            else f"   {key}: REDACTED_KEY"
462            for key, value in headers.items()
463        )
464        + "\n}"
465    )