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()
2def __init__(self, ):
3    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: Union[str, yarl.URL, NoneType], body: Any, headers: multidict._multidict.CIMultiDictProxy[str])
2def __init__(self, message, url, body, headers):
3    self.message = message
4    self.url = url
5    self.body = body
6    self.headers = headers
7    self.http_status = attr_dict['http_status'].default
8    BaseException.__init__(self, self.message,self.url,self.body,self.headers)

Method generated by attrs for class BadRequest.

url: Union[str, yarl.URL, NoneType]

The URL/endpoint caused this error.

body: Any

The response body.

headers: multidict._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        *,
 550        membership_type: enums.MembershipType | int = enums.MembershipType.ALL,
 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
 565        Other Parameters
 566        ----------------
 567        membership_type: `aiobungie.internal.enums.MembershipType`
 568            The Member ship type, if nothing was passed than it will return all.
 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    async def fetch_fireteams(
1083        self,
1084        activity_type: fireteams.FireteamActivity | int,
1085        *,
1086        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1087        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1088        date_range: int = 0,
1089        page: int = 0,
1090        slots_filter: int = 0,
1091    ) -> collections.Sequence[fireteams.Fireteam]:
1092        """Fetch public Bungie fireteams with open slots.
1093
1094        Parameters
1095        ----------
1096        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1097            The fireteam activity type.
1098
1099        Other Parameters
1100        ----------------
1101        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1102            If this is provided. Then the results will be filtered with the given platform.
1103            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1104        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1105            A locale language to filter the used language in that fireteam.
1106            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1107        date_range : `int`
1108            An integer to filter the date range of the returned fireteams. Defaults to `aiobungie.FireteamDate.ALL`.
1109        page : `int`
1110            The page number. By default its `0` which returns all available activities.
1111        slots_filter : `int`
1112            Filter the returned fireteams based on available slots. Default is `0`
1113
1114        Returns
1115        -------
1116        `collections.Sequence[fireteams.Fireteam]`
1117            A sequence of `aiobungie.crates.Fireteam`.
1118        """
1119
1120        resp = await self.rest.fetch_fireteams(
1121            activity_type,
1122            platform=platform,
1123            language=language,
1124            date_range=date_range,
1125            page=page,
1126            slots_filter=slots_filter,
1127        )
1128
1129        return self._framework.deserialize_fireteams(resp)
1130
1131    async def fetch_available_clan_fireteams(
1132        self,
1133        access_token: str,
1134        group_id: int,
1135        activity_type: fireteams.FireteamActivity | int,
1136        *,
1137        platform: fireteams.FireteamPlatform | int,
1138        language: fireteams.FireteamLanguage | str,
1139        date_range: int = 0,
1140        page: int = 0,
1141        public_only: bool = False,
1142        slots_filter: int = 0,
1143    ) -> collections.Sequence[fireteams.Fireteam]:
1144        """Fetch a clan's fireteams with open slots.
1145
1146        .. note::
1147            This method requires OAuth2: ReadGroups scope.
1148
1149        Parameters
1150        ----------
1151        access_token : `str`
1152            The bearer access token associated with the bungie account.
1153        group_id : `int`
1154            The group/clan id of the fireteam.
1155        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1156            The fireteam activity type.
1157
1158        Other Parameters
1159        ----------------
1160        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1161            If this is provided. Then the results will be filtered with the given platform.
1162            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1163        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1164            A locale language to filter the used language in that fireteam.
1165            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1166        date_range : `int`
1167            An integer to filter the date range of the returned fireteams. Defaults to `0`.
1168        page : `int`
1169            The page number. By default its `0` which returns all available activities.
1170        public_only: `bool`
1171            If set to True, Then only public fireteams will be returned.
1172        slots_filter : `int`
1173            Filter the returned fireteams based on available slots. Default is `0`
1174
1175        Returns
1176        -------
1177        `collections.Sequence[aiobungie.crates.Fireteam]`
1178            A sequence of  fireteams found in the clan.
1179            `None` will be returned if nothing was found.
1180        """
1181        resp = await self.rest.fetch_available_clan_fireteams(
1182            access_token,
1183            group_id,
1184            activity_type,
1185            platform=platform,
1186            language=language,
1187            date_range=date_range,
1188            page=page,
1189            public_only=public_only,
1190            slots_filter=slots_filter,
1191        )
1192
1193        return self._framework.deserialize_fireteams(resp)
1194
1195    async def fetch_clan_fireteam(
1196        self, access_token: str, fireteam_id: int, group_id: int
1197    ) -> fireteams.AvailableFireteam:
1198        """Fetch a specific clan fireteam.
1199
1200        .. note::
1201            This method requires OAuth2: ReadGroups scope.
1202
1203        Parameters
1204        ----------
1205        access_token : `str`
1206            The bearer access token associated with the bungie account.
1207        group_id : `int`
1208            The group/clan id to fetch the fireteam from.
1209        fireteam_id : `int`
1210            The fireteam id to fetch.
1211
1212        Returns
1213        -------
1214        `aiobungie.crates.AvailableFireteam`
1215            A sequence of available fireteams objects.
1216        """
1217        resp = await self.rest.fetch_clan_fireteam(access_token, fireteam_id, group_id)
1218
1219        return self._framework.deserialize_available_fireteam(resp)
1220
1221    async def fetch_my_clan_fireteams(
1222        self,
1223        access_token: str,
1224        group_id: int,
1225        *,
1226        include_closed: bool = True,
1227        platform: fireteams.FireteamPlatform | int,
1228        language: fireteams.FireteamLanguage | str,
1229        filtered: bool = True,
1230        page: int = 0,
1231    ) -> collections.Sequence[fireteams.AvailableFireteam]:
1232        """A method that's similar to `fetch_fireteams` but requires OAuth2.
1233
1234        .. note::
1235            This method requires OAuth2: ReadGroups scope.
1236
1237        Parameters
1238        ----------
1239        access_token : str
1240            The bearer access token associated with the bungie account.
1241        group_id : int
1242            The group/clan id to fetch.
1243
1244        Other Parameters
1245        ----------------
1246        include_closed : `bool`
1247            If provided and set to True, It will also return closed fireteams.
1248            If provided and set to False, It will only return public fireteams. Default is True.
1249        platform : aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int
1250            If this is provided. Then the results will be filtered with the given platform.
1251            Defaults to aiobungie.crates.FireteamPlatform.ANY which returns all platforms.
1252        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1253            A locale language to filter the used language in that fireteam.
1254            Defaults to aiobungie.crates.FireteamLanguage.ALL
1255        filtered : `bool`
1256            If set to True, it will filter by clan. Otherwise not. Default is True.
1257        page : `int`
1258            The page number. By default its 0 which returns all available activities.
1259
1260        Returns
1261        -------
1262        `collections.Sequence[aiobungie.crates.AvailableFireteam]`
1263            A sequence of available fireteams objects if exists. else `None` will be returned.
1264        """
1265        resp = await self.rest.fetch_my_clan_fireteams(
1266            access_token,
1267            group_id,
1268            include_closed=include_closed,
1269            platform=platform,
1270            language=language,
1271            filtered=filtered,
1272            page=page,
1273        )
1274
1275        return self._framework.deserialize_available_fireteams(resp)
1276
1277    # Friends and social.
1278
1279    async def fetch_friends(
1280        self, access_token: str, /
1281    ) -> collections.Sequence[friends.Friend]:
1282        """Fetch bungie friend list.
1283
1284        .. note::
1285            This requests OAuth2: ReadUserData scope.
1286
1287        Parameters
1288        -----------
1289        access_token : `str`
1290            The bearer access token associated with the bungie account.
1291
1292        Returns
1293        -------
1294        `collections.Sequence[aiobungie.crates.Friend]`
1295            A sequence of the friends associated with that access token.
1296        """
1297
1298        resp = await self.rest.fetch_friends(access_token)
1299
1300        return self._framework.deserialize_friends(resp)
1301
1302    async def fetch_friend_requests(
1303        self, access_token: str, /
1304    ) -> friends.FriendRequestView:
1305        """Fetch pending bungie friend requests queue.
1306
1307        .. note::
1308            This requests OAuth2: ReadUserData scope.
1309
1310        Parameters
1311        -----------
1312        access_token : `str`
1313            The bearer access token associated with the bungie account.
1314
1315        Returns
1316        -------
1317        `aiobungie.crates.FriendRequestView`
1318            A friend requests view of that associated access token.
1319        """
1320
1321        resp = await self.rest.fetch_friend_requests(access_token)
1322
1323        return self._framework.deserialize_friend_requests(resp)
1324
1325    # Applications and Developer portal.
1326
1327    async def fetch_application(self, appid: int, /) -> application.Application:
1328        """Fetch a Bungie application.
1329
1330        Parameters
1331        -----------
1332        appid: `int`
1333            The application id.
1334
1335        Returns
1336        --------
1337        `aiobungie.crates.Application`
1338            A Bungie application.
1339        """
1340        resp = await self.rest.fetch_application(appid)
1341
1342        return self._framework.deserialize_application(resp)
1343
1344    # Milestones
1345
1346    async def fetch_public_milestone_content(
1347        self, milestone_hash: int, /
1348    ) -> milestones.MilestoneContent:
1349        """Fetch the milestone content given its hash.
1350
1351        Parameters
1352        ----------
1353        milestone_hash : `int`
1354            The milestone hash.
1355
1356        Returns
1357        -------
1358        `aiobungie.crates.milestones.MilestoneContent`
1359            A milestone content object.
1360        """
1361        ...
1362        resp = await self.rest.fetch_public_milestone_content(milestone_hash)
1363        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: aiobungie.builders.Settings | None = None, max_retries: int = 4, debug: Union[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: aiobungie.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: RESTClient
127    @property
128    def rest(self) -> api.RESTClient:
129        return self._rest

Returns the REST client for the this client.

metadata: 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: aiobungie.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, /) -> aiobungie.crates.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, /) -> aiobungie.crates.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.iter.Iterator[aiobungie.crates.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) -> Sequence[aiobungie.crates.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: CredentialType | int = <CredentialType.STEAMID: 12>, /) -> aiobungie.crates.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: MembershipType | int = <MembershipType.NONE: 0>) -> aiobungie.crates.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, /) -> Sequence[aiobungie.crates.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, /) -> aiobungie.crates.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: MembershipType | int, components: Sequence[ComponentType], auth: str | None = None) -> aiobungie.crates.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: MembershipType | int, /, *, all: bool = False) -> aiobungie.crates.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: MembershipType | int = <MembershipType.ALL: -1>) -> Sequence[aiobungie.crates.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: MembershipType | int, character_id: int, components: Sequence[ComponentType], auth: str | None = None) -> aiobungie.crates.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: MembershipType | int) -> Sequence[aiobungie.crates.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: GameMode | int, *, membership_type: MembershipType | int = <MembershipType.ALL: -1>, page: int = 0, limit: int = 250) -> sain.iter.Iterator[aiobungie.crates.Activity]:
544    async def fetch_activities(
545        self,
546        member_id: int,
547        character_id: int,
548        mode: enums.GameMode | int,
549        *,
550        membership_type: enums.MembershipType | int = enums.MembershipType.ALL,
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
565        Other Parameters
566        ----------------
567        membership_type: `aiobungie.internal.enums.MembershipType`
568            The Member ship type, if nothing was passed than it will return all.
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
  • member_id (int): The user id that starts with 4611.
  • character_id (int): The id of the character to retrieve the activities for.
  • mode (aiobungie.aiobungie.internal.enums.GameMode | int): This parameter filters the game mode, Nightfall, Strike, Iron Banner, etc.
Other Parameters
  • membership_type (aiobungie.internal.enums.MembershipType): The Member ship type, if nothing was passed than it will return all.
  • 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, /) -> aiobungie.crates.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: MembershipType | int) -> sain.iter.Iterator[aiobungie.crates.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) -> aiobungie.crates.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: GroupType | int = <GroupType.CLAN: 1>) -> aiobungie.crates.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, /) -> Sequence[aiobungie.crates.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.iter.Iterator[aiobungie.crates.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: MembershipType | int, /, *, filter: int = 0, group_type: GroupType = <GroupType.CLAN: 1>) -> Sequence[aiobungie.crates.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: MembershipType | int, /, *, filter: int = 0, group_type: GroupType | int = <GroupType.CLAN: 1>) -> Sequence[aiobungie.crates.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: MembershipType | int = <MembershipType.NONE: 0>) -> sain.iter.Iterator[aiobungie.crates.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) -> Sequence[aiobungie.crates.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: MembershipType | int) -> aiobungie.crates.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) -> aiobungie.crates.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: GroupType | int, *, creation_date: GroupDate | int = 0, sort_by: int | None = None, group_member_count_filter: Optional[Literal[0, 1, 2, 3]] = 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) -> Sequence[aiobungie.crates.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, /) -> aiobungie.crates.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, /) -> aiobungie.crates.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.iter.Iterator[aiobungie.crates.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
async def fetch_fireteams( self, activity_type: FireteamActivity | int, *, platform: FireteamPlatform | int = <FireteamPlatform.ANY: 0>, language: FireteamLanguage | str = <FireteamLanguage.ALL: >, date_range: int = 0, page: int = 0, slots_filter: int = 0) -> Sequence[aiobungie.crates.Fireteam]:
1082    async def fetch_fireteams(
1083        self,
1084        activity_type: fireteams.FireteamActivity | int,
1085        *,
1086        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1087        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1088        date_range: int = 0,
1089        page: int = 0,
1090        slots_filter: int = 0,
1091    ) -> collections.Sequence[fireteams.Fireteam]:
1092        """Fetch public Bungie fireteams with open slots.
1093
1094        Parameters
1095        ----------
1096        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1097            The fireteam activity type.
1098
1099        Other Parameters
1100        ----------------
1101        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1102            If this is provided. Then the results will be filtered with the given platform.
1103            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1104        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1105            A locale language to filter the used language in that fireteam.
1106            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1107        date_range : `int`
1108            An integer to filter the date range of the returned fireteams. Defaults to `aiobungie.FireteamDate.ALL`.
1109        page : `int`
1110            The page number. By default its `0` which returns all available activities.
1111        slots_filter : `int`
1112            Filter the returned fireteams based on available slots. Default is `0`
1113
1114        Returns
1115        -------
1116        `collections.Sequence[fireteams.Fireteam]`
1117            A sequence of `aiobungie.crates.Fireteam`.
1118        """
1119
1120        resp = await self.rest.fetch_fireteams(
1121            activity_type,
1122            platform=platform,
1123            language=language,
1124            date_range=date_range,
1125            page=page,
1126            slots_filter=slots_filter,
1127        )
1128
1129        return self._framework.deserialize_fireteams(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: FireteamActivity | int, *, platform: FireteamPlatform | int, language: FireteamLanguage | str, date_range: int = 0, page: int = 0, public_only: bool = False, slots_filter: int = 0) -> Sequence[aiobungie.crates.Fireteam]:
1131    async def fetch_available_clan_fireteams(
1132        self,
1133        access_token: str,
1134        group_id: int,
1135        activity_type: fireteams.FireteamActivity | int,
1136        *,
1137        platform: fireteams.FireteamPlatform | int,
1138        language: fireteams.FireteamLanguage | str,
1139        date_range: int = 0,
1140        page: int = 0,
1141        public_only: bool = False,
1142        slots_filter: int = 0,
1143    ) -> collections.Sequence[fireteams.Fireteam]:
1144        """Fetch a clan's fireteams with open slots.
1145
1146        .. note::
1147            This method requires OAuth2: ReadGroups scope.
1148
1149        Parameters
1150        ----------
1151        access_token : `str`
1152            The bearer access token associated with the bungie account.
1153        group_id : `int`
1154            The group/clan id of the fireteam.
1155        activity_type : `aiobungie.aiobungie.crates.FireteamActivity | int`
1156            The fireteam activity type.
1157
1158        Other Parameters
1159        ----------------
1160        platform : `aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int`
1161            If this is provided. Then the results will be filtered with the given platform.
1162            Defaults to `aiobungie.crates.FireteamPlatform.ANY` which returns all platforms.
1163        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1164            A locale language to filter the used language in that fireteam.
1165            Defaults to `aiobungie.crates.FireteamLanguage.ALL`
1166        date_range : `int`
1167            An integer to filter the date range of the returned fireteams. Defaults to `0`.
1168        page : `int`
1169            The page number. By default its `0` which returns all available activities.
1170        public_only: `bool`
1171            If set to True, Then only public fireteams will be returned.
1172        slots_filter : `int`
1173            Filter the returned fireteams based on available slots. Default is `0`
1174
1175        Returns
1176        -------
1177        `collections.Sequence[aiobungie.crates.Fireteam]`
1178            A sequence of  fireteams found in the clan.
1179            `None` will be returned if nothing was found.
1180        """
1181        resp = await self.rest.fetch_available_clan_fireteams(
1182            access_token,
1183            group_id,
1184            activity_type,
1185            platform=platform,
1186            language=language,
1187            date_range=date_range,
1188            page=page,
1189            public_only=public_only,
1190            slots_filter=slots_filter,
1191        )
1192
1193        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) -> aiobungie.crates.AvailableFireteam:
1195    async def fetch_clan_fireteam(
1196        self, access_token: str, fireteam_id: int, group_id: int
1197    ) -> fireteams.AvailableFireteam:
1198        """Fetch a specific clan fireteam.
1199
1200        .. note::
1201            This method requires OAuth2: ReadGroups scope.
1202
1203        Parameters
1204        ----------
1205        access_token : `str`
1206            The bearer access token associated with the bungie account.
1207        group_id : `int`
1208            The group/clan id to fetch the fireteam from.
1209        fireteam_id : `int`
1210            The fireteam id to fetch.
1211
1212        Returns
1213        -------
1214        `aiobungie.crates.AvailableFireteam`
1215            A sequence of available fireteams objects.
1216        """
1217        resp = await self.rest.fetch_clan_fireteam(access_token, fireteam_id, group_id)
1218
1219        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: FireteamPlatform | int, language: FireteamLanguage | str, filtered: bool = True, page: int = 0) -> Sequence[aiobungie.crates.AvailableFireteam]:
1221    async def fetch_my_clan_fireteams(
1222        self,
1223        access_token: str,
1224        group_id: int,
1225        *,
1226        include_closed: bool = True,
1227        platform: fireteams.FireteamPlatform | int,
1228        language: fireteams.FireteamLanguage | str,
1229        filtered: bool = True,
1230        page: int = 0,
1231    ) -> collections.Sequence[fireteams.AvailableFireteam]:
1232        """A method that's similar to `fetch_fireteams` but requires OAuth2.
1233
1234        .. note::
1235            This method requires OAuth2: ReadGroups scope.
1236
1237        Parameters
1238        ----------
1239        access_token : str
1240            The bearer access token associated with the bungie account.
1241        group_id : int
1242            The group/clan id to fetch.
1243
1244        Other Parameters
1245        ----------------
1246        include_closed : `bool`
1247            If provided and set to True, It will also return closed fireteams.
1248            If provided and set to False, It will only return public fireteams. Default is True.
1249        platform : aiobungie.aiobungie.crates.fireteams.FireteamPlatform | int
1250            If this is provided. Then the results will be filtered with the given platform.
1251            Defaults to aiobungie.crates.FireteamPlatform.ANY which returns all platforms.
1252        language : `aiobungie.crates.fireteams.FireteamLanguage | str`
1253            A locale language to filter the used language in that fireteam.
1254            Defaults to aiobungie.crates.FireteamLanguage.ALL
1255        filtered : `bool`
1256            If set to True, it will filter by clan. Otherwise not. Default is True.
1257        page : `int`
1258            The page number. By default its 0 which returns all available activities.
1259
1260        Returns
1261        -------
1262        `collections.Sequence[aiobungie.crates.AvailableFireteam]`
1263            A sequence of available fireteams objects if exists. else `None` will be returned.
1264        """
1265        resp = await self.rest.fetch_my_clan_fireteams(
1266            access_token,
1267            group_id,
1268            include_closed=include_closed,
1269            platform=platform,
1270            language=language,
1271            filtered=filtered,
1272            page=page,
1273        )
1274
1275        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, /) -> Sequence[aiobungie.crates.Friend]:
1279    async def fetch_friends(
1280        self, access_token: str, /
1281    ) -> collections.Sequence[friends.Friend]:
1282        """Fetch bungie friend list.
1283
1284        .. note::
1285            This requests OAuth2: ReadUserData scope.
1286
1287        Parameters
1288        -----------
1289        access_token : `str`
1290            The bearer access token associated with the bungie account.
1291
1292        Returns
1293        -------
1294        `collections.Sequence[aiobungie.crates.Friend]`
1295            A sequence of the friends associated with that access token.
1296        """
1297
1298        resp = await self.rest.fetch_friends(access_token)
1299
1300        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, /) -> aiobungie.crates.FriendRequestView:
1302    async def fetch_friend_requests(
1303        self, access_token: str, /
1304    ) -> friends.FriendRequestView:
1305        """Fetch pending bungie friend requests queue.
1306
1307        .. note::
1308            This requests OAuth2: ReadUserData scope.
1309
1310        Parameters
1311        -----------
1312        access_token : `str`
1313            The bearer access token associated with the bungie account.
1314
1315        Returns
1316        -------
1317        `aiobungie.crates.FriendRequestView`
1318            A friend requests view of that associated access token.
1319        """
1320
1321        resp = await self.rest.fetch_friend_requests(access_token)
1322
1323        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, /) -> aiobungie.crates.Application:
1327    async def fetch_application(self, appid: int, /) -> application.Application:
1328        """Fetch a Bungie application.
1329
1330        Parameters
1331        -----------
1332        appid: `int`
1333            The application id.
1334
1335        Returns
1336        --------
1337        `aiobungie.crates.Application`
1338            A Bungie application.
1339        """
1340        resp = await self.rest.fetch_application(appid)
1341
1342        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, /) -> aiobungie.crates.MilestoneContent:
1346    async def fetch_public_milestone_content(
1347        self, milestone_hash: int, /
1348    ) -> milestones.MilestoneContent:
1349        """Fetch the milestone content given its hash.
1350
1351        Parameters
1352        ----------
1353        milestone_hash : `int`
1354            The milestone hash.
1355
1356        Returns
1357        -------
1358        `aiobungie.crates.milestones.MilestoneContent`
1359            A milestone content object.
1360        """
1361        ...
1362        resp = await self.rest.fetch_public_milestone_content(milestone_hash)
1363        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: 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: Union[str, yarl.URL, NoneType], body: Any, headers: multidict._multidict.CIMultiDictProxy[str], message: str, error_status: str, message_data: dict[str, str])
 2def __init__(self, *, error_code, throttle_seconds, url, body, headers, message, error_status, message_data):
 3    self.error_code = error_code
 4    self.throttle_seconds = throttle_seconds
 5    self.url = url
 6    self.body = body
 7    self.headers = headers
 8    self.message = message
 9    self.error_status = error_status
10    self.message_data = message_data
11    self.http_status = attr_dict['http_status'].default
12    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)
2def __init__(self, message, http_status):
3    self.message = message
4    self.http_status = http_status
5    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: Union[str, yarl.URL, NoneType], body: Any, headers: multidict._multidict.CIMultiDictProxy[str], message: str, error_status: str, message_data: dict[str, str])
 2def __init__(self, *, error_code, http_status, throttle_seconds, url, body, headers, message, error_status, message_data):
 3    self.error_code = error_code
 4    self.http_status = http_status
 5    self.throttle_seconds = throttle_seconds
 6    self.url = url
 7    self.body = body
 8    self.headers = headers
 9    self.message = message
10    self.error_status = error_status
11    self.message_data = message_data
12    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: Union[str, yarl.URL, NoneType]

The URL/endpoint caused this error.

body: Any

The response body.

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

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

metadata: MutableMapping[typing.Any, typing.Any]
535    @property
536    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
537        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
539    @property
540    def is_alive(self) -> bool:
541        return self._session is not None

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

settings: aiobungie.builders.Settings
543    @property
544    def settings(self) -> builders.Settings:
545        return self._settings

Internal client settings used within the HTTP client session.

async def close(self) -> None:
547    async def close(self) -> None:
548        if self._session is None:
549            raise RuntimeError("REST client is not running.")
550
551        if self._owned_client:
552            await self._session.close()
553            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:
555    def open(self) -> None:
556        """Open a new client session. This is called internally with contextmanager usage."""
557        if self.is_alive and self._owned_client:
558            raise RuntimeError("Cannot open REST client when it's already open.")
559
560        if self._owned_client:
561            self._session = aiohttp.ClientSession(
562                connector=aiohttp.TCPConnector(
563                    use_dns_cache=self._settings.use_dns_cache,
564                    ttl_dns_cache=self._settings.ttl_dns_cache,
565                    ssl_context=self._settings.ssl_context,
566                    ssl=self._settings.ssl,
567                ),
568                connector_owner=True,
569                raise_for_status=False,
570                timeout=self._settings.http_timeout,
571                trust_env=self._settings.trust_env,
572                headers=self._settings.headers,
573            )

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

@typing.final
async def static_request( self, method: Literal['GET', 'DELETE', 'POST', 'PUT', 'PATCH'], path: str, *, auth: str | None = None, json: Mapping[str, typing.Any] | None = None, params: Mapping[str, typing.Any] | None = None) -> Mapping[str, typing.Any] | Sequence[Mapping[str, typing.Any]] | bytes | str | int | bool | None:
575    @typing.final
576    async def static_request(
577        self,
578        method: _HTTP_METHOD,
579        path: str,
580        *,
581        auth: str | None = None,
582        json: collections.Mapping[str, typing.Any] | None = None,
583        params: collections.Mapping[str, typing.Any] | None = None,
584    ) -> typedefs.JSONIsh:
585        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) -> aiobungie.builders.OAuthURL | None:
593    @typing.final
594    def build_oauth2_url(
595        self, client_id: int | None = None
596    ) -> builders.OAuthURL | None:
597        client_id = client_id or self._client_id
598        if client_id is None:
599            return None
600
601        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, /) -> aiobungie.builders.OAuth2Response:
824    async def fetch_oauth2_tokens(self, code: str, /) -> builders.OAuth2Response:
825        data = {
826            "grant_type": "authorization_code",
827            "code": code,
828            "client_id": self._client_id,
829            "client_secret": self._client_secret,
830        }
831
832        response = await self._request(_POST, "", data=data, oauth2=True)
833        assert isinstance(response, dict)
834        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, /) -> aiobungie.builders.OAuth2Response:
836    async def refresh_access_token(
837        self, refresh_token: str, /
838    ) -> builders.OAuth2Response:
839        data = {
840            "grant_type": "refresh_token",
841            "refresh_token": refresh_token,
842            "client_id": self._client_id,
843            "client_secret": self._client_secret,
844        }
845
846        response = await self._request(_POST, "", data=data, oauth2=True)
847        assert isinstance(response, dict)
848        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) -> Mapping[str, typing.Any]:
850    async def fetch_bungie_user(self, id: int) -> typedefs.JSONObject:
851        resp = await self._request(_GET, f"User/GetBungieNetUserById/{id}/")
852        assert isinstance(resp, dict)
853        return resp

Fetch a Bungie user by their id.

Parameters
  • id (int): The user id.
Returns
Raises
async def fetch_user_themes(self) -> Sequence[Mapping[str, typing.Any]]:
855    async def fetch_user_themes(self) -> typedefs.JSONArray:
856        resp = await self._request(_GET, "User/GetAvailableThemes/")
857        assert isinstance(resp, list)
858        return resp

Fetch all available user themes.

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

Fetch Bungie user's memberships from their id.

Parameters
Returns
Raises
async def fetch_membership( self, name: str, code: int, type: MembershipType | int = <MembershipType.ALL: -1>, /) -> Sequence[Mapping[str, typing.Any]]:
870    async def fetch_membership(
871        self,
872        name: str,
873        code: int,
874        type: enums.MembershipType | int = enums.MembershipType.ALL,
875        /,
876    ) -> typedefs.JSONArray:
877        resp = await self._request(
878            _POST,
879            f"Destiny2/SearchDestinyPlayerByBungieName/{int(type)}",
880            json={"displayName": name, "displayNameCode": code},
881        )
882        assert isinstance(resp, list)
883        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, /) -> Mapping[str, typing.Any]:
885    async def fetch_sanitized_membership(
886        self, membership_id: int, /
887    ) -> typedefs.JSONObject:
888        response = await self._request(
889            _GET, f"User/GetSanitizedPlatformDisplayNames/{membership_id}/"
890        )
891        assert isinstance(response, dict)
892        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, /) -> Mapping[str, typing.Any]:
894    async def search_users(self, name: str, /) -> typedefs.JSONObject:
895        resp = await self._request(
896            _POST,
897            "User/Search/GlobalName/0",
898            json={"displayNamePrefix": name},
899        )
900        assert isinstance(resp, dict)
901        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) -> Mapping[str, typing.Any]:
903    async def fetch_clan_from_id(
904        self, id: int, /, access_token: str | None = None
905    ) -> typedefs.JSONObject:
906        resp = await self._request(_GET, f"GroupV2/{id}", auth=access_token)
907        assert isinstance(resp, dict)
908        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: GroupType | int = <GroupType.CLAN: 1>) -> Mapping[str, typing.Any]:
910    async def fetch_clan(
911        self,
912        name: str,
913        /,
914        access_token: str | None = None,
915        *,
916        type: enums.GroupType | int = enums.GroupType.CLAN,
917    ) -> typedefs.JSONObject:
918        resp = await self._request(
919            _GET, f"GroupV2/Name/{name}/{int(type)}", auth=access_token
920        )
921        assert isinstance(resp, dict)
922        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: GroupType | int = <GroupType.CLAN: 1>, *, creation_date: GroupDate | int = 0, sort_by: int | None = None, group_member_count_filter: Optional[Literal[0, 1, 2, 3]] = 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) -> Mapping[str, typing.Any]:
924    async def search_group(
925        self,
926        name: str,
927        group_type: enums.GroupType | int = enums.GroupType.CLAN,
928        *,
929        creation_date: clans.GroupDate | int = 0,
930        sort_by: int | None = None,
931        group_member_count_filter: typing.Literal[0, 1, 2, 3] | None = None,
932        locale_filter: str | None = None,
933        tag_text: str | None = None,
934        items_per_page: int | None = None,
935        current_page: int | None = None,
936        request_token: str | None = None,
937    ) -> typedefs.JSONObject:
938        payload: collections.MutableMapping[str, typing.Any] = {"name": name}
939
940        # as the official documentation says, you're not allowed to use those fields
941        # on a clan search. it is safe to send the request with them being `null` but not filled with a value.
942        if (
943            group_type == enums.GroupType.CLAN
944            and group_member_count_filter is not None
945            and locale_filter
946            and tag_text
947        ):
948            raise ValueError(
949                "If you're searching for clans, (group_member_count_filter, locale_filter, tag_text) must be None."
950            )
951
952        payload["groupType"] = int(group_type)
953        payload["creationDate"] = int(creation_date)
954        payload["sortBy"] = sort_by
955        payload["groupMemberCount"] = group_member_count_filter
956        payload["locale"] = locale_filter
957        payload["tagText"] = tag_text
958        payload["itemsPerPage"] = items_per_page
959        payload["currentPage"] = current_page
960        payload["requestToken"] = request_token
961        payload["requestContinuationToken"] = request_token
962
963        resp = await self._request(_POST, "GroupV2/Search/", json=payload)
964        assert isinstance(resp, dict)
965        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, /) -> Mapping[str, typing.Any]:
967    async def fetch_clan_admins(self, clan_id: int, /) -> typedefs.JSONObject:
968        resp = await self._request(_GET, f"GroupV2/{clan_id}/AdminsAndFounder/")
969        assert isinstance(resp, dict)
970        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, /) -> Sequence[Mapping[str, typing.Any]]:
972    async def fetch_clan_conversations(self, clan_id: int, /) -> typedefs.JSONArray:
973        resp = await self._request(_GET, f"GroupV2/{clan_id}/OptionalConversations/")
974        assert isinstance(resp, list)
975        return resp

Fetch a clan's conversations.

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

Fetch a Bungie Application.

Parameters
  • appid (int): The application id.
Returns
async def fetch_character( self, member_id: int, membership_type: MembershipType | int, character_id: int, components: Sequence[ComponentType], auth: str | None = None) -> Mapping[str, typing.Any]:
982    async def fetch_character(
983        self,
984        member_id: int,
985        membership_type: enums.MembershipType | int,
986        character_id: int,
987        components: collections.Sequence[enums.ComponentType],
988        auth: str | None = None,
989    ) -> typedefs.JSONObject:
990        collector = _collect_components(components)
991        response = await self._request(
992            _GET,
993            f"Destiny2/{int(membership_type)}/Profile/{member_id}/"
994            f"Character/{character_id}/?components={collector}",
995            auth=auth,
996        )
997        assert isinstance(response, dict)
998        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: GameMode | int, membership_type: MembershipType | int = <MembershipType.ALL: -1>, *, page: int = 0, limit: int = 1) -> Mapping[str, typing.Any]:
1000    async def fetch_activities(
1001        self,
1002        member_id: int,
1003        character_id: int,
1004        mode: enums.GameMode | int,
1005        membership_type: enums.MembershipType | int = enums.MembershipType.ALL,
1006        *,
1007        page: int = 0,
1008        limit: int = 1,
1009    ) -> typedefs.JSONObject:
1010        resp = await self._request(
1011            _GET,
1012            f"Destiny2/{int(membership_type)}/Account/"
1013            f"{member_id}/Character/{character_id}/Stats/Activities"
1014            f"/?mode={int(mode)}&count={limit}&page={page}",
1015        )
1016        assert isinstance(resp, dict)
1017        return resp

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

Parameters
  • member_id (int): The user id that starts with 4611.
  • character_id (int): The id of the character to retrieve.
  • mode (aiobungie.aiobungie.GameMode | int): This parameter filters the game mode, Nightfall, Strike, Iron Banner, etc.
Other Parameters
Returns
Raises
async def fetch_vendor_sales(self) -> Mapping[str, typing.Any]:
1019    async def fetch_vendor_sales(self) -> typedefs.JSONObject:
1020        resp = await self._request(
1021            _GET,
1022            f"Destiny2/Vendors/?components={int(enums.ComponentType.VENDOR_SALES)}",
1023        )
1024        assert isinstance(resp, dict)
1025        return resp
async def fetch_profile( self, membership_id: int, type: MembershipType | int, components: Sequence[ComponentType], auth: str | None = None) -> Mapping[str, typing.Any]:
1027    async def fetch_profile(
1028        self,
1029        membership_id: int,
1030        type: enums.MembershipType | int,
1031        components: collections.Sequence[enums.ComponentType],
1032        auth: str | None = None,
1033    ) -> typedefs.JSONObject:
1034        collector = _collect_components(components)
1035        response = await self._request(
1036            _GET,
1037            f"Destiny2/{int(type)}/Profile/{membership_id}/?components={collector}",
1038            auth=auth,
1039        )
1040        assert isinstance(response, dict)
1041        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) -> Mapping[str, typing.Any]:
1043    async def fetch_entity(self, type: str, hash: int) -> typedefs.JSONObject:
1044        response = await self._request(_GET, route=f"Destiny2/Manifest/{type}/{hash}")
1045        assert isinstance(response, dict)
1046        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, /) -> Mapping[str, typing.Any]:
1048    async def fetch_inventory_item(self, hash: int, /) -> typedefs.JSONObject:
1049        resp = await self.fetch_entity("DestinyInventoryItemDefinition", hash)
1050        assert isinstance(resp, dict)
1051        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, /) -> Mapping[str, typing.Any]:
1053    async def fetch_objective_entity(self, hash: int, /) -> typedefs.JSONObject:
1054        resp = await self.fetch_entity("DestinyObjectiveDefinition", hash)
1055        assert isinstance(resp, dict)
1056        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: MembershipType | int, /, *, filter: int = 0, group_type: GroupType | int = <GroupType.CLAN: 1>) -> Mapping[str, typing.Any]:
1058    async def fetch_groups_for_member(
1059        self,
1060        member_id: int,
1061        member_type: enums.MembershipType | int,
1062        /,
1063        *,
1064        filter: int = 0,
1065        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1066    ) -> typedefs.JSONObject:
1067        resp = await self._request(
1068            _GET,
1069            f"GroupV2/User/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1070        )
1071        assert isinstance(resp, dict)
1072        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: MembershipType | int, /, *, filter: int = 0, group_type: GroupType | int = <GroupType.CLAN: 1>) -> Mapping[str, typing.Any]:
1074    async def fetch_potential_groups_for_member(
1075        self,
1076        member_id: int,
1077        member_type: enums.MembershipType | int,
1078        /,
1079        *,
1080        filter: int = 0,
1081        group_type: enums.GroupType | int = enums.GroupType.CLAN,
1082    ) -> typedefs.JSONObject:
1083        resp = await self._request(
1084            _GET,
1085            f"GroupV2/User/Potential/{int(member_type)}/{member_id}/{filter}/{int(group_type)}/",
1086        )
1087        assert isinstance(resp, dict)
1088        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: MembershipType | int = <MembershipType.NONE: 0>) -> Mapping[str, typing.Any]:
1090    async def fetch_clan_members(
1091        self,
1092        clan_id: int,
1093        /,
1094        *,
1095        name: str | None = None,
1096        type: enums.MembershipType | int = enums.MembershipType.NONE,
1097    ) -> typedefs.JSONObject:
1098        resp = await self._request(
1099            _GET,
1100            f"/GroupV2/{clan_id}/Members/?memberType={int(type)}&nameSearch={name if name else ''}&currentpage=1",
1101        )
1102        assert isinstance(resp, dict)
1103        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: CredentialType | int = <CredentialType.STEAMID: 12>, /) -> Mapping[str, typing.Any]:
1105    async def fetch_hardlinked_credentials(
1106        self,
1107        credential: int,
1108        type: enums.CredentialType | int = enums.CredentialType.STEAMID,
1109        /,
1110    ) -> typedefs.JSONObject:
1111        resp = await self._request(
1112            _GET,
1113            f"User/GetMembershipFromHardLinkedCredential/{int(type)}/{credential}/",
1114        )
1115        assert isinstance(resp, dict)
1116        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, /) -> Sequence[Mapping[str, typing.Any]]:
1118    async def fetch_user_credentials(
1119        self, access_token: str, membership_id: int, /
1120    ) -> typedefs.JSONArray:
1121        resp = await self._request(
1122            _GET,
1123            f"User/GetCredentialTypesForTargetAccount/{membership_id}",
1124            auth=access_token,
1125        )
1126        assert isinstance(resp, list)
1127        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: aiobungie.builders.PlugSocketBuilder | Mapping[str, int], character_id: int, membership_type: MembershipType | int) -> Mapping[str, typing.Any]:
1129    async def insert_socket_plug(
1130        self,
1131        action_token: str,
1132        /,
1133        instance_id: int,
1134        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1135        character_id: int,
1136        membership_type: enums.MembershipType | int,
1137    ) -> typedefs.JSONObject:
1138        if isinstance(plug, builders.PlugSocketBuilder):
1139            plug = plug.collect()
1140
1141        body = {
1142            "actionToken": action_token,
1143            "itemInstanceId": instance_id,
1144            "plug": plug,
1145            "characterId": character_id,
1146            "membershipType": int(membership_type),
1147        }
1148        resp = await self._request(
1149            _POST, "Destiny2/Actions/Items/InsertSocketPlug", json=body
1150        )
1151        assert isinstance(resp, dict)
1152        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: aiobungie.builders.PlugSocketBuilder | Mapping[str, int], character_id: int, membership_type: MembershipType | int) -> Mapping[str, typing.Any]:
1154    async def insert_socket_plug_free(
1155        self,
1156        access_token: str,
1157        /,
1158        instance_id: int,
1159        plug: builders.PlugSocketBuilder | collections.Mapping[str, int],
1160        character_id: int,
1161        membership_type: enums.MembershipType | int,
1162    ) -> typedefs.JSONObject:
1163        if isinstance(plug, builders.PlugSocketBuilder):
1164            plug = plug.collect()
1165
1166        body = {
1167            "itemInstanceId": instance_id,
1168            "plug": plug,
1169            "characterId": character_id,
1170            "membershipType": int(membership_type),
1171        }
1172        resp = await self._request(
1173            _POST,
1174            "Destiny2/Actions/Items/InsertSocketPlugFree",
1175            json=body,
1176            auth=access_token,
1177        )
1178        assert isinstance(resp, dict)
1179        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: MembershipType | int) -> int:
1181    @helpers.unstable
1182    async def set_item_lock_state(
1183        self,
1184        access_token: str,
1185        state: bool,
1186        /,
1187        item_id: int,
1188        character_id: int,
1189        membership_type: enums.MembershipType | int,
1190    ) -> int:
1191        body = {
1192            "state": state,
1193            "itemId": item_id,
1194            "characterId": character_id,
1195            "membershipType": int(membership_type),
1196        }
1197        response = await self._request(
1198            _POST,
1199            "Destiny2/Actions/Items/SetLockState",
1200            json=body,
1201            auth=access_token,
1202        )
1203        assert isinstance(response, int)
1204        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: MembershipType | int) -> int:
1206    async def set_quest_track_state(
1207        self,
1208        access_token: str,
1209        state: bool,
1210        /,
1211        item_id: int,
1212        character_id: int,
1213        membership_type: enums.MembershipType | int,
1214    ) -> int:
1215        body = {
1216            "state": state,
1217            "itemId": item_id,
1218            "characterId": character_id,
1219            "membership_type": int(membership_type),
1220        }
1221        response = await self._request(
1222            _POST,
1223            "Destiny2/Actions/Items/SetTrackedState",
1224            json=body,
1225            auth=access_token,
1226        )
1227        assert isinstance(response, int)
1228        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) -> Mapping[str, typing.Any]:
1230    async def fetch_manifest_path(self) -> typedefs.JSONObject:
1231        path = await self._request(_GET, "Destiny2/Manifest")
1232        assert isinstance(path, dict)
1233        return path

Fetch the manifest JSON paths.

Returns
  • typedefs.JSONObject: The manifest JSON paths.
async def read_manifest_bytes( self, language: Literal['en', 'fr', 'es', 'es-mx', 'de', 'it', 'ja', 'pt-br', 'ru', 'pl', 'ko', 'zh-cht', 'zh-chs'] = 'en', /) -> bytes:
1235    async def read_manifest_bytes(self, language: _ALLOWED_LANGS = "en", /) -> bytes:
1236        _ensure_manifest_language(language)
1237
1238        content = await self.fetch_manifest_path()
1239        resp = await self._request(
1240            _GET,
1241            content["mobileWorldContentPaths"][language],
1242            unwrap_bytes=True,
1243            base=True,
1244        )
1245        assert isinstance(resp, bytes)
1246        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: Literal['en', 'fr', 'es', 'es-mx', 'de', 'it', 'ja', 'pt-br', 'ru', 'pl', 'ko', 'zh-cht', 'zh-chs'] = 'en', name: str = 'manifest', path: pathlib.Path | str = '.', *, force: bool = False, executor: concurrent.futures._base.Executor | None = None) -> pathlib.Path:
1248    async def download_sqlite_manifest(
1249        self,
1250        language: _ALLOWED_LANGS = "en",
1251        name: str = "manifest",
1252        path: pathlib.Path | str = ".",
1253        *,
1254        force: bool = False,
1255        executor: concurrent.futures.Executor | None = None,
1256    ) -> pathlib.Path:
1257        complete_path = _get_path(name, path, sql=True)
1258
1259        if complete_path.exists():
1260            if force:
1261                _LOGGER.info(
1262                    f"Found manifest in {complete_path!s}. Forcing to Re-Download."
1263                )
1264                complete_path.unlink(missing_ok=True)
1265
1266                return await self.download_sqlite_manifest(
1267                    language, name, path, force=force
1268                )
1269
1270            else:
1271                raise FileExistsError(
1272                    "Manifest file already exists, "
1273                    "To force download, set the `force` parameter to `True`."
1274                )
1275
1276        _LOGGER.info(f"Downloading manifest. Location: {complete_path!s}")
1277        data_bytes = await self.read_manifest_bytes(language)
1278        await asyncio.get_running_loop().run_in_executor(
1279            executor, _write_sqlite_bytes, data_bytes, path, name
1280        )
1281        _LOGGER.info("Finished downloading manifest.")
1282        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: Literal['en', 'fr', 'es', 'es-mx', 'de', 'it', 'ja', 'pt-br', 'ru', 'pl', 'ko', 'zh-cht', 'zh-chs'] = 'en', executor: concurrent.futures._base.Executor | None = None) -> pathlib.Path:
1284    async def download_json_manifest(
1285        self,
1286        file_name: str = "manifest",
1287        path: str | pathlib.Path = ".",
1288        *,
1289        language: _ALLOWED_LANGS = "en",
1290        executor: concurrent.futures.Executor | None = None,
1291    ) -> pathlib.Path:
1292        _ensure_manifest_language(language)
1293        full_path = _get_path(file_name, path)
1294        _LOGGER.info(f"Downloading manifest JSON to {full_path!r}...")
1295
1296        content = await self.fetch_manifest_path()
1297        json_bytes = await self._request(
1298            _GET,
1299            content["jsonWorldContentPaths"][language],
1300            unwrap_bytes=True,
1301            base=True,
1302        )
1303
1304        assert isinstance(json_bytes, bytes)
1305        await asyncio.get_running_loop().run_in_executor(
1306            executor, _write_json_bytes, json_bytes, file_name, path
1307        )
1308        _LOGGER.info("Finished downloading manifest JSON.")
1309        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:
1311    async def fetch_manifest_version(self) -> str:
1312        # This is guaranteed str.
1313        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: MembershipType | int, /, *, all: bool = False) -> Mapping[str, typing.Any]:
1315    async def fetch_linked_profiles(
1316        self,
1317        member_id: int,
1318        member_type: enums.MembershipType | int,
1319        /,
1320        *,
1321        all: bool = False,
1322    ) -> typedefs.JSONObject:
1323        resp = await self._request(
1324            _GET,
1325            f"Destiny2/{int(member_type)}/Profile/{member_id}/LinkedProfiles/?getAllMemberships={all}",
1326        )
1327        assert isinstance(resp, dict)
1328        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) -> Mapping[str, typing.Any]:
1330    async def fetch_clan_banners(self) -> typedefs.JSONObject:
1331        resp = await self._request(_GET, "Destiny2/Clan/ClanBannerDictionary/")
1332        assert isinstance(resp, dict)
1333        return resp

Fetch the values of the clan banners.

Returns
async def fetch_public_milestones(self) -> Mapping[str, typing.Any]:
1335    async def fetch_public_milestones(self) -> typedefs.JSONObject:
1336        resp = await self._request(_GET, "Destiny2/Milestones/")
1337        assert isinstance(resp, dict)
1338        return resp

Fetch the available milestones.

Returns
async def fetch_public_milestone_content(self, milestone_hash: int, /) -> Mapping[str, typing.Any]:
1340    async def fetch_public_milestone_content(
1341        self, milestone_hash: int, /
1342    ) -> typedefs.JSONObject:
1343        resp = await self._request(
1344            _GET, f"Destiny2/Milestones/{milestone_hash}/Content/"
1345        )
1346        assert isinstance(resp, dict)
1347        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, /) -> Mapping[str, typing.Any]:
1349    async def fetch_current_user_memberships(
1350        self, access_token: str, /
1351    ) -> typedefs.JSONObject:
1352        resp = await self._request(
1353            _GET,
1354            "User/GetMembershipsForCurrentUser/",
1355            auth=access_token,
1356        )
1357        assert isinstance(resp, dict)
1358        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: MembershipType | int) -> None:
1360    async def equip_item(
1361        self,
1362        access_token: str,
1363        /,
1364        item_id: int,
1365        character_id: int,
1366        membership_type: enums.MembershipType | int,
1367    ) -> None:
1368        payload = {
1369            "itemId": item_id,
1370            "characterId": character_id,
1371            "membershipType": int(membership_type),
1372        }
1373
1374        await self._request(
1375            _POST,
1376            "Destiny2/Actions/Items/EquipItem/",
1377            json=payload,
1378            auth=access_token,
1379        )

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: Sequence[int], character_id: int, membership_type: MembershipType | int) -> None:
1381    async def equip_items(
1382        self,
1383        access_token: str,
1384        /,
1385        item_ids: collections.Sequence[int],
1386        character_id: int,
1387        membership_type: enums.MembershipType | int,
1388    ) -> None:
1389        payload = {
1390            "itemIds": item_ids,
1391            "characterId": character_id,
1392            "membershipType": int(membership_type),
1393        }
1394        await self._request(
1395            _POST,
1396            "Destiny2/Actions/Items/EquipItems/",
1397            json=payload,
1398            auth=access_token,
1399        )

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: MembershipType | int, *, length: int = 0, comment: str | None = None) -> None:
1401    async def ban_clan_member(
1402        self,
1403        access_token: str,
1404        /,
1405        group_id: int,
1406        membership_id: int,
1407        membership_type: enums.MembershipType | int,
1408        *,
1409        length: int = 0,
1410        comment: str | None = None,
1411    ) -> None:
1412        payload = {"comment": str(comment), "length": length}
1413        await self._request(
1414            _POST,
1415            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Ban/",
1416            json=payload,
1417            auth=access_token,
1418        )

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: MembershipType | int) -> None:
1420    async def unban_clan_member(
1421        self,
1422        access_token: str,
1423        /,
1424        group_id: int,
1425        membership_id: int,
1426        membership_type: enums.MembershipType | int,
1427    ) -> None:
1428        await self._request(
1429            _POST,
1430            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Unban/",
1431            auth=access_token,
1432        )

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: MembershipType | int) -> Mapping[str, typing.Any]:
1434    async def kick_clan_member(
1435        self,
1436        access_token: str,
1437        /,
1438        group_id: int,
1439        membership_id: int,
1440        membership_type: enums.MembershipType | int,
1441    ) -> typedefs.JSONObject:
1442        resp = await self._request(
1443            _POST,
1444            f"GroupV2/{group_id}/Members/{int(membership_type)}/{membership_id}/Kick/",
1445            auth=access_token,
1446        )
1447        assert isinstance(resp, dict)
1448        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: Sequence[str] | None = None, is_public: bool | None = None, locale: str | None = None, avatar_image_index: int | None = None, membership_option: MembershipOption | int | None = None, allow_chat: bool | None = None, chat_security: Optional[Literal[0, 1]] = None, call_sign: str | None = None, homepage: Optional[Literal[0, 1, 2]] = None, enable_invite_messaging_for_admins: bool | None = None, default_publicity: Optional[Literal[0, 1, 2]] = None, is_public_topic_admin: bool | None = None) -> None:
1450    async def edit_clan(
1451        self,
1452        access_token: str,
1453        /,
1454        group_id: int,
1455        *,
1456        name: str | None = None,
1457        about: str | None = None,
1458        motto: str | None = None,
1459        theme: str | None = None,
1460        tags: collections.Sequence[str] | None = None,
1461        is_public: bool | None = None,
1462        locale: str | None = None,
1463        avatar_image_index: int | None = None,
1464        membership_option: enums.MembershipOption | int | None = None,
1465        allow_chat: bool | None = None,
1466        chat_security: typing.Literal[0, 1] | None = None,
1467        call_sign: str | None = None,
1468        homepage: typing.Literal[0, 1, 2] | None = None,
1469        enable_invite_messaging_for_admins: bool | None = None,
1470        default_publicity: typing.Literal[0, 1, 2] | None = None,
1471        is_public_topic_admin: bool | None = None,
1472    ) -> None:
1473        payload = {
1474            "name": name,
1475            "about": about,
1476            "motto": motto,
1477            "theme": theme,
1478            "tags": tags,
1479            "isPublic": is_public,
1480            "avatarImageIndex": avatar_image_index,
1481            "isPublicTopicAdminOnly": is_public_topic_admin,
1482            "allowChat": allow_chat,
1483            "chatSecurity": chat_security,
1484            "callsign": call_sign,
1485            "homepage": homepage,
1486            "enableInvitationMessagingForAdmins": enable_invite_messaging_for_admins,
1487            "defaultPublicity": default_publicity,
1488            "locale": locale,
1489        }
1490        if membership_option is not None:
1491            payload["membershipOption"] = int(membership_option)
1492
1493        await self._request(
1494            _POST,
1495            f"GroupV2/{group_id}/Edit",
1496            json=payload,
1497            auth=access_token,
1498        )

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: Optional[Literal[0, 1, 2]] = None, update_banner_permission_override: bool | None = None, join_level: ClanMemberType | int | None = None) -> None:
1500    async def edit_clan_options(
1501        self,
1502        access_token: str,
1503        /,
1504        group_id: int,
1505        *,
1506        invite_permissions_override: bool | None = None,
1507        update_culture_permissionOverride: bool | None = None,
1508        host_guided_game_permission_override: typing.Literal[0, 1, 2] | None = None,
1509        update_banner_permission_override: bool | None = None,
1510        join_level: enums.ClanMemberType | int | None = None,
1511    ) -> None:
1512        payload = {
1513            "InvitePermissionOverride": invite_permissions_override,
1514            "UpdateCulturePermissionOverride": update_culture_permissionOverride,
1515            "HostGuidedGamePermissionOverride": host_guided_game_permission_override,
1516            "UpdateBannerPermissionOverride": update_banner_permission_override,
1517            "JoinLevel": int(join_level) if join_level else None,
1518        }
1519
1520        await self._request(
1521            _POST,
1522            f"GroupV2/{group_id}/EditFounderOptions",
1523            json=payload,
1524            auth=access_token,
1525        )

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: Sequence[int], reason_category_hashes: Sequence[int]) -> None:
1527    async def report_player(
1528        self,
1529        access_token: str,
1530        /,
1531        activity_id: int,
1532        character_id: int,
1533        reason_hashes: collections.Sequence[int],
1534        reason_category_hashes: collections.Sequence[int],
1535    ) -> None:
1536        await self._request(
1537            _POST,
1538            f"Destiny2/Stats/PostGameCarnageReport/{activity_id}/Report/",
1539            json={
1540                "reasonCategoryHashes": reason_category_hashes,
1541                "reasonHashes": reason_hashes,
1542                "offendingCharacterId": character_id,
1543            },
1544            auth=access_token,
1545        )

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, /) -> Mapping[str, typing.Any]:
1547    async def fetch_friends(self, access_token: str, /) -> typedefs.JSONObject:
1548        resp = await self._request(
1549            _GET,
1550            "Social/Friends/",
1551            auth=access_token,
1552        )
1553        assert isinstance(resp, dict)
1554        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, /) -> Mapping[str, typing.Any]:
1556    async def fetch_friend_requests(self, access_token: str, /) -> typedefs.JSONObject:
1557        resp = await self._request(
1558            _GET,
1559            "Social/Friends/Requests",
1560            auth=access_token,
1561        )
1562        assert isinstance(resp, dict)
1563        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:
1565    async def accept_friend_request(self, access_token: str, /, member_id: int) -> None:
1566        await self._request(
1567            _POST,
1568            f"Social/Friends/Requests/Accept/{member_id}",
1569            auth=access_token,
1570        )

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:
1572    async def send_friend_request(self, access_token: str, /, member_id: int) -> None:
1573        await self._request(
1574            _POST,
1575            f"Social/Friends/Add/{member_id}",
1576            auth=access_token,
1577        )

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:
1579    async def decline_friend_request(
1580        self, access_token: str, /, member_id: int
1581    ) -> None:
1582        await self._request(
1583            _POST,
1584            f"Social/Friends/Requests/Decline/{member_id}",
1585            auth=access_token,
1586        )

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:
1588    async def remove_friend(self, access_token: str, /, member_id: int) -> None:
1589        await self._request(
1590            _POST,
1591            f"Social/Friends/Remove/{member_id}",
1592            auth=access_token,
1593        )

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:
1595    async def remove_friend_request(self, access_token: str, /, member_id: int) -> None:
1596        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1597        await self._request(
1598            _POST,
1599            f"Social/Friends/Requests/Remove/{member_id}",
1600            auth=access_token,
1601        )

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:
1603    async def approve_all_pending_group_users(
1604        self,
1605        access_token: str,
1606        /,
1607        group_id: int,
1608        message: str | None = None,
1609    ) -> None:
1610        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1611        await self._request(
1612            _POST,
1613            f"GroupV2/{group_id}/Members/ApproveAll",
1614            auth=access_token,
1615            json={"message": str(message)},
1616        )

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:
1618    async def deny_all_pending_group_users(
1619        self,
1620        access_token: str,
1621        /,
1622        group_id: int,
1623        *,
1624        message: str | None = None,
1625    ) -> None:
1626        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1627        await self._request(
1628            _POST,
1629            f"GroupV2/{group_id}/Members/DenyAll",
1630            auth=access_token,
1631            json={"message": str(message)},
1632        )

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: Literal[0, 1] = 0) -> None:
1634    async def add_optional_conversation(
1635        self,
1636        access_token: str,
1637        /,
1638        group_id: int,
1639        *,
1640        name: str | None = None,
1641        security: typing.Literal[0, 1] = 0,
1642    ) -> None:
1643        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1644        payload = {"chatName": str(name), "chatSecurity": security}
1645        await self._request(
1646            _POST,
1647            f"GroupV2/{group_id}/OptionalConversations/Add",
1648            json=payload,
1649            auth=access_token,
1650        )

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: Literal[0, 1] = 0, enable_chat: bool = False) -> None:
1652    async def edit_optional_conversation(
1653        self,
1654        access_token: str,
1655        /,
1656        group_id: int,
1657        conversation_id: int,
1658        *,
1659        name: str | None = None,
1660        security: typing.Literal[0, 1] = 0,
1661        enable_chat: bool = False,
1662    ) -> None:
1663        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1664        payload = {
1665            "chatEnabled": enable_chat,
1666            "chatName": str(name),
1667            "chatSecurity": security,
1668        }
1669        await self._request(
1670            _POST,
1671            f"GroupV2/{group_id}/OptionalConversations/Edit/{conversation_id}",
1672            json=payload,
1673            auth=access_token,
1674        )

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

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: MembershipType | int, *, stack_size: int = 1, vault: bool = False) -> None:
1704    async def pull_item(
1705        self,
1706        access_token: str,
1707        /,
1708        item_id: int,
1709        item_hash: int,
1710        character_id: int,
1711        member_type: enums.MembershipType | int,
1712        *,
1713        stack_size: int = 1,
1714        vault: bool = False,
1715    ) -> None:
1716        # <<inherited docstring from aiobungie.interfaces.rest.RESTInterface>>
1717        payload = {
1718            "characterId": character_id,
1719            "membershipType": int(member_type),
1720            "itemId": item_id,
1721            "itemReferenceHash": item_hash,
1722            "stackSize": stack_size,
1723        }
1724        await self._request(
1725            _POST,
1726            "Destiny2/Actions/Items/PullFromPostmaster",
1727            json=payload,
1728            auth=access_token,
1729        )
1730        if vault:
1731            await self.transfer_item(
1732                access_token,
1733                item_id=item_id,
1734                item_hash=item_hash,
1735                character_id=character_id,
1736                member_type=member_type,
1737                stack_size=stack_size,
1738                vault=True,
1739            )

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.
async def fetch_fireteams( self, activity_type: FireteamActivity | int, *, platform: FireteamPlatform | int = <FireteamPlatform.ANY: 0>, language: FireteamLanguage | str = <FireteamLanguage.ALL: >, date_range: FireteamDate | int = <FireteamDate.ALL: 0>, page: int = 0, slots_filter: int = 0) -> Mapping[str, typing.Any]:
1741    async def fetch_fireteams(
1742        self,
1743        activity_type: fireteams.FireteamActivity | int,
1744        *,
1745        platform: fireteams.FireteamPlatform | int = fireteams.FireteamPlatform.ANY,
1746        language: fireteams.FireteamLanguage | str = fireteams.FireteamLanguage.ALL,
1747        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1748        page: int = 0,
1749        slots_filter: int = 0,
1750    ) -> typedefs.JSONObject:
1751        resp = await self._request(
1752            _GET,
1753            f"Fireteam/Search/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{page}/?langFilter={str(language)}",  # noqa: E501 Line too long
1754        )
1755        assert isinstance(resp, dict)
1756        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: FireteamActivity | int, *, platform: FireteamPlatform | int, language: FireteamLanguage | str, date_range: FireteamDate | int = <FireteamDate.ALL: 0>, page: int = 0, public_only: bool = False, slots_filter: int = 0) -> Mapping[str, typing.Any]:
1758    async def fetch_available_clan_fireteams(
1759        self,
1760        access_token: str,
1761        group_id: int,
1762        activity_type: fireteams.FireteamActivity | int,
1763        *,
1764        platform: fireteams.FireteamPlatform | int,
1765        language: fireteams.FireteamLanguage | str,
1766        date_range: fireteams.FireteamDate | int = fireteams.FireteamDate.ALL,
1767        page: int = 0,
1768        public_only: bool = False,
1769        slots_filter: int = 0,
1770    ) -> typedefs.JSONObject:
1771        resp = await self._request(
1772            _GET,
1773            f"Fireteam/Clan/{group_id}/Available/{int(platform)}/{int(activity_type)}/{int(date_range)}/{slots_filter}/{public_only}/{page}",  # noqa: E501
1774            json={"langFilter": str(language)},
1775            auth=access_token,
1776        )
1777        assert isinstance(resp, dict)
1778        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) -> Mapping[str, typing.Any]:
1780    async def fetch_clan_fireteam(
1781        self, access_token: str, fireteam_id: int, group_id: int
1782    ) -> typedefs.JSONObject:
1783        resp = await self._request(
1784            _GET,
1785            f"Fireteam/Clan/{group_id}/Summary/{fireteam_id}",
1786            auth=access_token,
1787        )
1788        assert isinstance(resp, dict)
1789        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: FireteamPlatform | int, language: FireteamLanguage | str, filtered: bool = True, page: int = 0) -> Mapping[str, typing.Any]:
1791    async def fetch_my_clan_fireteams(
1792        self,
1793        access_token: str,
1794        group_id: int,
1795        *,
1796        include_closed: bool = True,
1797        platform: fireteams.FireteamPlatform | int,
1798        language: fireteams.FireteamLanguage | str,
1799        filtered: bool = True,
1800        page: int = 0,
1801    ) -> typedefs.JSONObject:
1802        payload = {"groupFilter": filtered, "langFilter": str(language)}
1803
1804        resp = await self._request(
1805            _GET,
1806            f"Fireteam/Clan/{group_id}/My/{int(platform)}/{include_closed}/{page}",
1807            json=payload,
1808            auth=access_token,
1809        )
1810        assert isinstance(resp, dict)
1811        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:
1813    async def fetch_private_clan_fireteams(
1814        self, access_token: str, group_id: int, /
1815    ) -> int:
1816        resp = await self._request(
1817            _GET,
1818            f"Fireteam/Clan/{group_id}/ActiveCount",
1819            auth=access_token,
1820        )
1821        assert isinstance(resp, int)
1822        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, /) -> Mapping[str, typing.Any]:
1824    async def fetch_post_activity(self, instance_id: int, /) -> typedefs.JSONObject:
1825        resp = await self._request(
1826            _GET, f"Destiny2/Stats/PostGameCarnageReport/{instance_id}"
1827        )
1828        assert isinstance(resp, dict)
1829        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) -> Mapping[str, typing.Any]:
1831    @helpers.unstable
1832    async def search_entities(
1833        self, name: str, entity_type: str, *, page: int = 0
1834    ) -> typedefs.JSONObject:
1835        resp = await self._request(
1836            _GET,
1837            f"Destiny2/Armory/Search/{entity_type}/{name}/",
1838            json={"page": page},
1839        )
1840        assert isinstance(resp, dict)
1841        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: MembershipType | int) -> Mapping[str, typing.Any]:
1843    async def fetch_unique_weapon_history(
1844        self,
1845        membership_id: int,
1846        character_id: int,
1847        membership_type: enums.MembershipType | int,
1848    ) -> typedefs.JSONObject:
1849        resp = await self._request(
1850            _GET,
1851            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/UniqueWeapons/",
1852        )
1853        assert isinstance(resp, dict)
1854        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: MembershipType | int, components: Sequence[ComponentType]) -> Mapping[str, typing.Any]:
1856    async def fetch_item(
1857        self,
1858        member_id: int,
1859        item_id: int,
1860        membership_type: enums.MembershipType | int,
1861        components: collections.Sequence[enums.ComponentType],
1862    ) -> typedefs.JSONObject:
1863        collector = _collect_components(components)
1864
1865        resp = await self._request(
1866            _GET,
1867            f"Destiny2/{int(membership_type)}/Profile/{member_id}/Item/{item_id}/?components={collector}",
1868        )
1869        assert isinstance(resp, dict)
1870        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, /) -> Mapping[str, typing.Any]:
1872    async def fetch_clan_weekly_rewards(self, clan_id: int, /) -> typedefs.JSONObject:
1873        resp = await self._request(_GET, f"Destiny2/Clan/{clan_id}/WeeklyRewardState/")
1874        assert isinstance(resp, dict)
1875        return resp

Fetch the weekly reward state for a clan.

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

Fetch available locales at Bungie.

Returns
async def fetch_common_settings(self) -> Mapping[str, typing.Any]:
1882    async def fetch_common_settings(self) -> typedefs.JSONObject:
1883        resp = await self._request(_GET, "Settings")
1884        assert isinstance(resp, dict)
1885        return resp

Fetch the common settings used by Bungie's environment.

Returns
async def fetch_user_systems_overrides(self) -> Mapping[str, typing.Any]:
1887    async def fetch_user_systems_overrides(self) -> typedefs.JSONObject:
1888        resp = await self._request(_GET, "UserSystemOverrides")
1889        assert isinstance(resp, dict)
1890        return resp

Fetch a user's specific system overrides.

Returns
async def fetch_global_alerts( self, *, include_streaming: bool = False) -> Sequence[Mapping[str, typing.Any]]:
1892    async def fetch_global_alerts(
1893        self, *, include_streaming: bool = False
1894    ) -> typedefs.JSONArray:
1895        resp = await self._request(
1896            _GET, f"GlobalAlerts/?includestreaming={include_streaming}"
1897        )
1898        assert isinstance(resp, list)
1899        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: Literal[0, 1], membership_type: MembershipType | int, /, *, affected_item_id: int | None = None, character_id: int | None = None) -> Mapping[str, typing.Any]:
1901    async def awainitialize_request(
1902        self,
1903        access_token: str,
1904        type: typing.Literal[0, 1],
1905        membership_type: enums.MembershipType | int,
1906        /,
1907        *,
1908        affected_item_id: int | None = None,
1909        character_id: int | None = None,
1910    ) -> typedefs.JSONObject:
1911        body = {"type": type, "membershipType": int(membership_type)}
1912
1913        if affected_item_id is not None:
1914            body["affectedItemId"] = affected_item_id
1915
1916        if character_id is not None:
1917            body["characterId"] = character_id
1918
1919        resp = await self._request(
1920            _POST, "Destiny2/Awa/Initialize", json=body, auth=access_token
1921        )
1922        assert isinstance(resp, dict)
1923        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, /) -> Mapping[str, typing.Any]:
1925    async def awaget_action_token(
1926        self, access_token: str, correlation_id: str, /
1927    ) -> typedefs.JSONObject:
1928        resp = await self._request(
1929            _POST,
1930            f"Destiny2/Awa/GetActionToken/{correlation_id}",
1931            auth=access_token,
1932        )
1933        assert isinstance(resp, dict)
1934        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: MutableSequence[str | bytes]) -> int:
1936    async def awa_provide_authorization_result(
1937        self,
1938        access_token: str,
1939        selection: int,
1940        correlation_id: str,
1941        nonce: collections.MutableSequence[str | bytes],
1942    ) -> int:
1943        body = {"selection": selection, "correlationId": correlation_id, "nonce": nonce}
1944
1945        resp = await self._request(
1946            _POST,
1947            "Destiny2/Awa/AwaProvideAuthorizationResult",
1948            json=body,
1949            auth=access_token,
1950        )
1951        assert isinstance(resp, int)
1952        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: MembershipType | int, /, components: Sequence[ComponentType], filter: int | None = None) -> Mapping[str, typing.Any]:
1954    async def fetch_vendors(
1955        self,
1956        access_token: str,
1957        character_id: int,
1958        membership_id: int,
1959        membership_type: enums.MembershipType | int,
1960        /,
1961        components: collections.Sequence[enums.ComponentType],
1962        filter: int | None = None,
1963    ) -> typedefs.JSONObject:
1964        components_ = _collect_components(components)
1965        route = (
1966            f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1967            f"/Character/{character_id}/Vendors/?components={components_}"
1968        )
1969
1970        if filter is not None:
1971            route = route + f"&filter={filter}"
1972
1973        resp = await self._request(
1974            _GET,
1975            route,
1976            auth=access_token,
1977        )
1978        assert isinstance(resp, dict)
1979        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: MembershipType | int, vendor_hash: int, /, components: Sequence[ComponentType]) -> Mapping[str, typing.Any]:
1981    async def fetch_vendor(
1982        self,
1983        access_token: str,
1984        character_id: int,
1985        membership_id: int,
1986        membership_type: enums.MembershipType | int,
1987        vendor_hash: int,
1988        /,
1989        components: collections.Sequence[enums.ComponentType],
1990    ) -> typedefs.JSONObject:
1991        components_ = _collect_components(components)
1992        resp = await self._request(
1993            _GET,
1994            (
1995                f"Destiny2/{int(membership_type)}/Profile/{membership_id}"
1996                f"/Character/{character_id}/Vendors/{vendor_hash}/?components={components_}"
1997            ),
1998            auth=access_token,
1999        )
2000        assert isinstance(resp, dict)
2001        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) -> Mapping[str, typing.Any]:
2003    async def fetch_application_api_usage(
2004        self,
2005        access_token: str,
2006        application_id: int,
2007        /,
2008        *,
2009        start: datetime.datetime | None = None,
2010        end: datetime.datetime | None = None,
2011    ) -> typedefs.JSONObject:
2012        end_date, start_date = time.parse_date_range(end, start)
2013        resp = await self._request(
2014            _GET,
2015            f"App/ApiUsage/{application_id}/?end={end_date}&start={start_date}",
2016            auth=access_token,
2017        )
2018        assert isinstance(resp, dict)
2019        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) -> Sequence[Mapping[str, typing.Any]]:
2021    async def fetch_bungie_applications(self) -> typedefs.JSONArray:
2022        resp = await self._request(_GET, "App/FirstParty")
2023        assert isinstance(resp, list)
2024        return resp

Fetch details for applications created by Bungie.

Returns
async def fetch_content_type(self, type: str, /) -> Mapping[str, typing.Any]:
2026    async def fetch_content_type(self, type: str, /) -> typedefs.JSONObject:
2027        resp = await self._request(_GET, f"Content/GetContentType/{type}/")
2028        assert isinstance(resp, dict)
2029        return resp
async def fetch_content_by_id( self, id: int, locale: str, /, *, head: bool = False) -> Mapping[str, typing.Any]:
2031    async def fetch_content_by_id(
2032        self, id: int, locale: str, /, *, head: bool = False
2033    ) -> typedefs.JSONObject:
2034        resp = await self._request(
2035            _GET,
2036            f"Content/GetContentById/{id}/{locale}/",
2037            json={"head": head},
2038        )
2039        assert isinstance(resp, dict)
2040        return resp
async def fetch_content_by_tag_and_type( self, locale: str, tag: str, type: str, *, head: bool = False) -> Mapping[str, typing.Any]:
2042    async def fetch_content_by_tag_and_type(
2043        self, locale: str, tag: str, type: str, *, head: bool = False
2044    ) -> typedefs.JSONObject:
2045        resp = await self._request(
2046            _GET,
2047            f"Content/GetContentByTagAndType/{tag}/{type}/{locale}/",
2048            json={"head": head},
2049        )
2050        assert isinstance(resp, dict)
2051        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) -> Mapping[str, typing.Any]:
2053    async def search_content_with_text(
2054        self,
2055        locale: str,
2056        /,
2057        content_type: str,
2058        search_text: str,
2059        tag: str,
2060        *,
2061        page: int | None = None,
2062        source: str | None = None,
2063    ) -> typedefs.JSONObject:
2064        body: typedefs.JSONObject = {
2065            "locale": locale,
2066            "currentpage": page or 1,
2067            "ctype": content_type,
2068            "searchtxt": search_text,
2069            "searchtext": search_text,
2070            "tag": tag,
2071            "source": source,
2072        }
2073
2074        resp = await self._request(_GET, "Content/Search", params=body)
2075        assert isinstance(resp, dict)
2076        return resp
async def search_content_by_tag_and_type( self, locale: str, tag: str, type: str, *, page: int | None = None) -> Mapping[str, typing.Any]:
2078    async def search_content_by_tag_and_type(
2079        self,
2080        locale: str,
2081        tag: str,
2082        type: str,
2083        *,
2084        page: int | None = None,
2085    ) -> typedefs.JSONObject:
2086        body: typedefs.JSONObject = {"currentpage": page or 1}
2087
2088        resp = await self._request(
2089            _GET,
2090            f"Content/SearchContentByTagAndType/{tag}/{type}/{locale}/",
2091            params=body,
2092        )
2093        assert isinstance(resp, dict)
2094        return resp
async def search_help_articles(self, text: str, size: str, /) -> Mapping[str, typing.Any]:
2096    async def search_help_articles(
2097        self, text: str, size: str, /
2098    ) -> typedefs.JSONObject:
2099        resp = await self._request(_GET, f"Content/SearchHelpArticles/{text}/{size}/")
2100        assert isinstance(resp, dict)
2101        return resp
async def fetch_topics_page( self, category_filter: int, group: int, date_filter: int, sort: str | bytes, *, page: int | None = None, locales: Iterable[str] | None = None, tag_filter: str | None = None) -> Mapping[str, typing.Any]:
2103    async def fetch_topics_page(
2104        self,
2105        category_filter: int,
2106        group: int,
2107        date_filter: int,
2108        sort: str | bytes,
2109        *,
2110        page: int | None = None,
2111        locales: collections.Iterable[str] | None = None,
2112        tag_filter: str | None = None,
2113    ) -> typedefs.JSONObject:
2114        params = {
2115            "locales": ",".join(locales) if locales is not None else "en",
2116        }
2117        if tag_filter:
2118            params["tagstring"] = tag_filter
2119
2120        resp = await self._request(
2121            _GET,
2122            f"Forum/GetTopicsPaged/{page or 0}/0/{group}/{sort!s}/{date_filter}/{category_filter}/",
2123            params=params,
2124        )
2125        assert isinstance(resp, dict)
2126        return resp
async def fetch_core_topics_page( self, category_filter: int, date_filter: int, sort: str | bytes, *, page: int | None = None, locales: Iterable[str] | None = None) -> Mapping[str, typing.Any]:
2128    async def fetch_core_topics_page(
2129        self,
2130        category_filter: int,
2131        date_filter: int,
2132        sort: str | bytes,
2133        *,
2134        page: int | None = None,
2135        locales: collections.Iterable[str] | None = None,
2136    ) -> typedefs.JSONObject:
2137        resp = await self._request(
2138            _GET,
2139            f"Forum/GetCoreTopicsPaged/{page or 0}"
2140            f"/{sort!s}/{date_filter}/{category_filter}/?locales={','.join(locales) if locales else 'en'}",
2141        )
2142        assert isinstance(resp, dict)
2143        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) -> Mapping[str, typing.Any]:
2145    async def fetch_posts_threaded_page(
2146        self,
2147        parent_post: bool,
2148        page: int,
2149        page_size: int,
2150        parent_post_id: int,
2151        reply_size: int,
2152        root_thread_mode: bool,
2153        sort_mode: int,
2154        show_banned: str | None = None,
2155    ) -> typedefs.JSONObject:
2156        resp = await self._request(
2157            _GET,
2158            f"Forum/GetPostsThreadedPaged/{parent_post}/{page}/"
2159            f"{page_size}/{reply_size}/{parent_post_id}/{root_thread_mode}/{sort_mode}/",
2160            json={"showbanned": show_banned},
2161        )
2162        assert isinstance(resp, dict)
2163        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) -> Mapping[str, typing.Any]:
2165    async def fetch_posts_threaded_page_from_child(
2166        self,
2167        child_id: bool,
2168        page: int,
2169        page_size: int,
2170        reply_size: int,
2171        root_thread_mode: bool,
2172        sort_mode: int,
2173        show_banned: str | None = None,
2174    ) -> typedefs.JSONObject:
2175        resp = await self._request(
2176            _GET,
2177            f"Forum/GetPostsThreadedPagedFromChild/{child_id}/"
2178            f"{page}/{page_size}/{reply_size}/{root_thread_mode}/{sort_mode}/",
2179            json={"showbanned": show_banned},
2180        )
2181        assert isinstance(resp, dict)
2182        return resp
async def fetch_post_and_parent( self, child_id: int, /, *, show_banned: str | None = None) -> Mapping[str, typing.Any]:
2184    async def fetch_post_and_parent(
2185        self, child_id: int, /, *, show_banned: str | None = None
2186    ) -> typedefs.JSONObject:
2187        resp = await self._request(
2188            _GET,
2189            f"Forum/GetPostAndParent/{child_id}/",
2190            json={"showbanned": show_banned},
2191        )
2192        assert isinstance(resp, dict)
2193        return resp
async def fetch_posts_and_parent_awaiting( self, child_id: int, /, *, show_banned: str | None = None) -> Mapping[str, typing.Any]:
2195    async def fetch_posts_and_parent_awaiting(
2196        self, child_id: int, /, *, show_banned: str | None = None
2197    ) -> typedefs.JSONObject:
2198        resp = await self._request(
2199            _GET,
2200            f"Forum/GetPostAndParentAwaitingApproval/{child_id}/",
2201            json={"showbanned": show_banned},
2202        )
2203        assert isinstance(resp, dict)
2204        return resp
async def fetch_topic_for_content(self, content_id: int, /) -> int:
2206    async def fetch_topic_for_content(self, content_id: int, /) -> int:
2207        resp = await self._request(_GET, f"Forum/GetTopicForContent/{content_id}/")
2208        assert isinstance(resp, int)
2209        return resp
async def fetch_forum_tag_suggestions(self, partial_tag: str, /) -> Mapping[str, typing.Any]:
2211    async def fetch_forum_tag_suggestions(
2212        self, partial_tag: str, /
2213    ) -> typedefs.JSONObject:
2214        resp = await self._request(
2215            _GET,
2216            "Forum/GetForumTagSuggestions/",
2217            json={"partialtag": partial_tag},
2218        )
2219        assert isinstance(resp, dict)
2220        return resp
async def fetch_poll(self, topic_id: int, /) -> Mapping[str, typing.Any]:
2222    async def fetch_poll(self, topic_id: int, /) -> typedefs.JSONObject:
2223        resp = await self._request(_GET, f"Forum/Poll/{topic_id}/")
2224        assert isinstance(resp, dict)
2225        return resp
async def fetch_recruitment_thread_summaries(self) -> Sequence[Mapping[str, typing.Any]]:
2227    async def fetch_recruitment_thread_summaries(self) -> typedefs.JSONArray:
2228        resp = await self._request(_POST, "Forum/Recruit/Summaries/")
2229        assert isinstance(resp, list)
2230        return resp
async def fetch_available_avatars(self) -> Mapping[str, int]:
2248    async def fetch_available_avatars(self) -> collections.Mapping[str, int]:
2249        resp = await self._request(_GET, "GroupV2/GetAvailableAvatars/")
2250        assert isinstance(resp, dict)
2251        return resp
async def fetch_user_clan_invite_setting( self, access_token: str, /, membership_type: MembershipType | int) -> bool:
2253    async def fetch_user_clan_invite_setting(
2254        self,
2255        access_token: str,
2256        /,
2257        membership_type: enums.MembershipType | int,
2258    ) -> bool:
2259        resp = await self._request(
2260            _GET,
2261            f"GroupV2/GetUserClanInviteSetting/{int(membership_type)}/",
2262            auth=access_token,
2263        )
2264        assert isinstance(resp, bool)
2265        return resp
async def fetch_banned_group_members( self, access_token: str, group_id: int, /, *, page: int = 1) -> Mapping[str, typing.Any]:
2267    async def fetch_banned_group_members(
2268        self, access_token: str, group_id: int, /, *, page: int = 1
2269    ) -> typedefs.JSONObject:
2270        resp = await self._request(
2271            _GET,
2272            f"GroupV2/{group_id}/Banned/?currentpage={page}",
2273            auth=access_token,
2274        )
2275        assert isinstance(resp, dict)
2276        return resp
async def fetch_pending_group_memberships( self, access_token: str, group_id: int, /, *, current_page: int = 1) -> Mapping[str, typing.Any]:
2278    async def fetch_pending_group_memberships(
2279        self, access_token: str, group_id: int, /, *, current_page: int = 1
2280    ) -> typedefs.JSONObject:
2281        resp = await self._request(
2282            _GET,
2283            f"GroupV2/{group_id}/Members/Pending/?currentpage={current_page}",
2284            auth=access_token,
2285        )
2286        assert isinstance(resp, dict)
2287        return resp
async def fetch_invited_group_memberships( self, access_token: str, group_id: int, /, *, current_page: int = 1) -> Mapping[str, typing.Any]:
2289    async def fetch_invited_group_memberships(
2290        self, access_token: str, group_id: int, /, *, current_page: int = 1
2291    ) -> typedefs.JSONObject:
2292        resp = await self._request(
2293            _GET,
2294            f"GroupV2/{group_id}/Members/InvitedIndividuals/?currentpage={current_page}",
2295            auth=access_token,
2296        )
2297        assert isinstance(resp, dict)
2298        return resp
async def invite_member_to_group( self, access_token: str, /, group_id: int, membership_id: int, membership_type: MembershipType | int, *, message: str | None = None) -> Mapping[str, typing.Any]:
2300    async def invite_member_to_group(
2301        self,
2302        access_token: str,
2303        /,
2304        group_id: int,
2305        membership_id: int,
2306        membership_type: enums.MembershipType | int,
2307        *,
2308        message: str | None = None,
2309    ) -> typedefs.JSONObject:
2310        resp = await self._request(
2311            _POST,
2312            f"GroupV2/{group_id}/Members/IndividualInvite/{int(membership_type)}/{membership_id}/",
2313            auth=access_token,
2314            json={"message": str(message)},
2315        )
2316        assert isinstance(resp, dict)
2317        return resp
async def cancel_group_member_invite( self, access_token: str, /, group_id: int, membership_id: int, membership_type: MembershipType | int) -> Mapping[str, typing.Any]:
2319    async def cancel_group_member_invite(
2320        self,
2321        access_token: str,
2322        /,
2323        group_id: int,
2324        membership_id: int,
2325        membership_type: enums.MembershipType | int,
2326    ) -> typedefs.JSONObject:
2327        resp = await self._request(
2328            _POST,
2329            f"GroupV2/{group_id}/Members/IndividualInviteCancel/{int(membership_type)}/{membership_id}/",
2330            auth=access_token,
2331        )
2332        assert isinstance(resp, dict)
2333        return resp
async def fetch_historical_definition(self) -> Mapping[str, typing.Any]:
2335    async def fetch_historical_definition(self) -> typedefs.JSONObject:
2336        resp = await self._request(_GET, "Destiny2/Stats/Definition/")
2337        assert isinstance(resp, dict)
2338        return resp
async def fetch_historical_stats( self, character_id: int, membership_id: int, membership_type: MembershipType | int, day_start: datetime.datetime, day_end: datetime.datetime, groups: Sequence[aiobungie.internal.enums.StatsGroupType | int], modes: Sequence[GameMode | int], *, period_type: aiobungie.internal.enums.PeriodType = <PeriodType.ALL_TIME: 2>) -> Mapping[str, typing.Any]:
2340    async def fetch_historical_stats(
2341        self,
2342        character_id: int,
2343        membership_id: int,
2344        membership_type: enums.MembershipType | int,
2345        day_start: datetime.datetime,
2346        day_end: datetime.datetime,
2347        groups: collections.Sequence[enums.StatsGroupType | int],
2348        modes: collections.Sequence[enums.GameMode | int],
2349        *,
2350        period_type: enums.PeriodType = enums.PeriodType.ALL_TIME,
2351    ) -> typedefs.JSONObject:
2352        end, start = time.parse_date_range(day_end, day_start)
2353        resp = await self._request(
2354            _GET,
2355            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Character/{character_id}/Stats/",
2356            json={
2357                "dayend": end,
2358                "daystart": start,
2359                "groups": [str(int(group)) for group in groups],
2360                "modes": [str(int(mode)) for mode in modes],
2361                "periodType": int(period_type),
2362            },
2363        )
2364        assert isinstance(resp, dict)
2365        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: MembershipType | int, groups: Sequence[aiobungie.internal.enums.StatsGroupType | int]) -> Mapping[str, typing.Any]:
2367    async def fetch_historical_stats_for_account(
2368        self,
2369        membership_id: int,
2370        membership_type: enums.MembershipType | int,
2371        groups: collections.Sequence[enums.StatsGroupType | int],
2372    ) -> typedefs.JSONObject:
2373        resp = await self._request(
2374            _GET,
2375            f"Destiny2/{int(membership_type)}/Account/{membership_id}/Stats/",
2376            json={"groups": [str(int(group)) for group in groups]},
2377        )
2378        assert isinstance(resp, dict)
2379        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: MembershipType | int, /) -> Mapping[str, typing.Any]:
2381    async def fetch_aggregated_activity_stats(
2382        self,
2383        character_id: int,
2384        membership_id: int,
2385        membership_type: enums.MembershipType | int,
2386        /,
2387    ) -> typedefs.JSONObject:
2388        resp = await self._request(
2389            _GET,
2390            f"Destiny2/{int(membership_type)}/Account/{membership_id}/"
2391            f"Character/{character_id}/Stats/AggregateActivityStats/",
2392        )
2393        assert isinstance(resp, dict)
2394        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: MembershipType | int) -> None:
2396    async def equip_loadout(
2397        self,
2398        access_token: str,
2399        /,
2400        loadout_index: int,
2401        character_id: int,
2402        membership_type: enums.MembershipType | int,
2403    ) -> None:
2404        response = await self._request(
2405            _POST,
2406            "Destiny2/Actions/Loadouts/EquipLoadout/",
2407            json={
2408                "loadoutIndex": loadout_index,
2409                "characterId": character_id,
2410                "membership_type": int(membership_type),
2411            },
2412            auth=access_token,
2413        )
2414        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: MembershipType | int, *, color_hash: int | None = None, icon_hash: int | None = None, name_hash: int | None = None) -> None:
2416    async def snapshot_loadout(
2417        self,
2418        access_token: str,
2419        /,
2420        loadout_index: int,
2421        character_id: int,
2422        membership_type: enums.MembershipType | int,
2423        *,
2424        color_hash: int | None = None,
2425        icon_hash: int | None = None,
2426        name_hash: int | None = None,
2427    ) -> None:
2428        response = await self._request(
2429            _POST,
2430            "Destiny2/Actions/Loadouts/SnapshotLoadout/",
2431            auth=access_token,
2432            json={
2433                "colorHash": color_hash,
2434                "iconHash": icon_hash,
2435                "nameHash": name_hash,
2436                "loadoutIndex": loadout_index,
2437                "characterId": character_id,
2438                "membershipType": int(membership_type),
2439            },
2440        )
2441        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: MembershipType | int, *, color_hash: int | None = None, icon_hash: int | None = None, name_hash: int | None = None) -> None:
2443    async def update_loadout(
2444        self,
2445        access_token: str,
2446        /,
2447        loadout_index: int,
2448        character_id: int,
2449        membership_type: enums.MembershipType | int,
2450        *,
2451        color_hash: int | None = None,
2452        icon_hash: int | None = None,
2453        name_hash: int | None = None,
2454    ) -> None:
2455        response = await self._request(
2456            _POST,
2457            "Destiny2/Actions/Loadouts/UpdateLoadoutIdentifiers/",
2458            auth=access_token,
2459            json={
2460                "colorHash": color_hash,
2461                "iconHash": icon_hash,
2462                "nameHash": name_hash,
2463                "loadoutIndex": loadout_index,
2464                "characterId": character_id,
2465                "membershipType": int(membership_type),
2466            },
2467        )
2468        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: MembershipType | int) -> None:
2470    async def clear_loadout(
2471        self,
2472        access_token: str,
2473        /,
2474        loadout_index: int,
2475        character_id: int,
2476        membership_type: enums.MembershipType | int,
2477    ) -> None:
2478        response = await self._request(
2479            _POST,
2480            "Destiny2/Actions/Loadouts/ClearLoadout/",
2481            json={
2482                "loadoutIndex": loadout_index,
2483                "characterId": character_id,
2484                "membership_type": int(membership_type),
2485            },
2486            auth=access_token,
2487        )
2488        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:
2490    async def force_drops_repair(self, access_token: str, /) -> bool:
2491        response = await self._request(
2492            _POST, "Tokens/Partner/ForceDropsRepair/", auth=access_token
2493        )
2494        assert isinstance(response, bool)
2495        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:
2497    async def claim_partner_offer(
2498        self,
2499        access_token: str,
2500        /,
2501        *,
2502        offer_id: str,
2503        bungie_membership_id: int,
2504        transaction_id: str,
2505    ) -> bool:
2506        response = await self._request(
2507            _POST,
2508            "Tokens/Partner/ClaimOffer/",
2509            json={
2510                "PartnerOfferId": offer_id,
2511                "BungieNetMembershipId": bungie_membership_id,
2512                "TransactionId": transaction_id,
2513            },
2514            auth=access_token,
2515        )
2516        assert isinstance(response, bool)
2517        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) -> Mapping[str, typing.Any]:
2519    async def fetch_bungie_rewards_for_user(
2520        self, access_token: str, /, membership_id: int
2521    ) -> typedefs.JSONObject:
2522        response = await self._request(
2523            _GET,
2524            f"Tokens/Rewards/GetRewardsForUser/{membership_id}/",
2525            auth=access_token,
2526        )
2527        assert isinstance(response, dict)
2528        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: MembershipType | int) -> Mapping[str, typing.Any]:
2530    async def fetch_bungie_rewards_for_platform(
2531        self,
2532        access_token: str,
2533        /,
2534        membership_id: int,
2535        membership_type: enums.MembershipType | int,
2536    ) -> typedefs.JSONObject:
2537        response = await self._request(
2538            _GET,
2539            f"Tokens/Rewards/GetRewardsForPlatformUser/{membership_id}/{int(membership_type)}",
2540            auth=access_token,
2541        )
2542        assert isinstance(response, dict)
2543        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) -> Mapping[str, typing.Any]:
2545    async def fetch_bungie_rewards(self) -> typedefs.JSONObject:
2546        response = await self._request(_GET, "Tokens/Rewards/BungieRewards/")
2547        assert isinstance(response, dict)
2548        return response

Returns a list of the current bungie rewards.

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

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: aiobungie.builders.Settings | None = None, dumps: Callable[[Mapping[str, typing.Any] | Sequence[Mapping[str, typing.Any]]], bytes] = <function dumps>, loads: Callable[[str | bytes], Sequence[Mapping[str, typing.Any]] | Mapping[str, typing.Any]] = <function loads>, max_retries: int = 4, debug: Union[Literal['TRACE'], bool, int] = False)
273    def __init__(
274        self,
275        token: str,
276        /,
277        *,
278        client_secret: str | None = None,
279        client_id: int | None = None,
280        settings: builders.Settings | None = None,
281        dumps: typedefs.Dumps = helpers.dumps,
282        loads: typedefs.Loads = helpers.loads,
283        max_retries: int = 4,
284        debug: typing.Literal["TRACE"] | bool | int = False,
285    ) -> None:
286        self._client_secret = client_secret
287        self._client_id = client_id
288        self._token = token
289        self._max_retries = max_retries
290        self._metadata: collections.MutableMapping[typing.Any, typing.Any] = {}
291        self._enable_debug = debug
292        self._client_session: aiohttp.ClientSession | None = None
293        self._loads = loads
294        self._dumps = dumps
295        self._settings = settings or builders.Settings()
client_id: int | None
297    @property
298    def client_id(self) -> int | None:
299        """Return the client id of this REST client if provided, Otherwise None."""
300        return self._client_id

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

metadata: MutableMapping[typing.Any, typing.Any]
302    @property
303    def metadata(self) -> collections.MutableMapping[typing.Any, typing.Any]:
304        """A general-purpose mutable mapping you can use to store data.
305
306        This mapping can be accessed from any process that has a reference to this pool.
307        """
308        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: aiobungie.builders.Settings
310    @property
311    def settings(self) -> builders.Settings:
312        """Internal client settings used within the HTTP client session."""
313        return self._settings

Internal client settings used within the HTTP client session.

@typing.final
def build_oauth2_url(self, client_id: int | None = None) -> aiobungie.builders.OAuthURL | None:
321    @typing.final
322    def build_oauth2_url(
323        self, client_id: int | None = None
324    ) -> builders.OAuthURL | None:
325        """Construct a new `OAuthURL` url object.
326
327        You can get the complete string representation of the url by calling `.compile()` on it.
328
329        Parameters
330        ----------
331        client_id : `int | None`
332            An optional client id to provide, If left `None` it will roll back to the id passed
333            to the `RESTClient`, If both is `None` this method will return `None`.
334
335        Returns
336        -------
337        `aiobungie.builders.OAuthURL | None`
338            * If `client_id` was provided as a parameter, It guarantees to return a complete `OAuthURL` object
339            * If `client_id` is set to `aiobungie.RESTClient` will be.
340            * If both are `None` this method will return `None.
341        """
342        client_id = client_id or self._client_id
343        if client_id is None:
344            return None
345
346        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:
348    async def start(self) -> None:
349        """Start the TCP connection of this client pool.
350
351        This will raise `RuntimeError` if the connection has already been started.
352
353        Example
354        -------
355        ```py
356        pool = aiobungie.RESTPool(...)
357
358        async def run() -> None:
359            await pool.start()
360            async with pool.acquire() as client:
361                # use client
362
363        async def stop(self) -> None:
364            await pool.close()
365        ```
366        """
367        if self._client_session is not None:
368            raise RuntimeError("<RESTPool> has already been started.") from None
369
370        self._client_session = aiohttp.ClientSession(
371            connector=aiohttp.TCPConnector(
372                use_dns_cache=self._settings.use_dns_cache,
373                ttl_dns_cache=self._settings.ttl_dns_cache,
374                ssl_context=self._settings.ssl_context,
375                ssl=self._settings.ssl,
376            ),
377            connector_owner=True,
378            raise_for_status=False,
379            timeout=self._settings.http_timeout,
380            trust_env=self._settings.trust_env,
381            headers=self._settings.headers,
382        )

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:
384    async def stop(self) -> None:
385        """Stop the TCP connection of this client pool.
386
387        This will raise `RuntimeError` if the connection has already been closed.
388
389        Example
390        -------
391        ```py
392        pool = aiobungie.RESTPool(...)
393
394        async def run() -> None:
395            await pool.start()
396            async with pool.acquire() as client:
397                # use client
398
399        async def stop(self) -> None:
400            await pool.close()
401        ```
402        """
403        if self._client_session is None:
404            raise RuntimeError("<RESTPool> is already stopped.")
405
406        await self._client_session.close()
407        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:
409    @typing.final
410    def acquire(self) -> RESTClient:
411        """Acquires a new `RESTClient` instance from this pool.
412
413        Returns
414        -------
415        `RESTClient`
416            An instance of a `RESTClient`.
417        """
418        return RESTClient(
419            self._token,
420            client_secret=self._client_secret,
421            client_id=self._client_id,
422            loads=self._loads,
423            dumps=self._dumps,
424            max_retries=self._max_retries,
425            debug=self._enable_debug,
426            client_session=self._client_session,
427            owned_client=False,
428            settings=self._settings,
429        )

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: Union[str, yarl.URL], body: Any, retry_after: float = 0.0)
2def __init__(self, url, body, retry_after=attr_dict['retry_after'].default):
3    self.http_status = attr_dict['http_status'].default
4    self.url = url
5    self.body = body
6    self.retry_after = retry_after
7    self.message = __attr_factory_message(self)
8    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: Union[str, yarl.URL]

The URL/endpoint caused this error.

body: 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: Union[str, yarl.URL, NoneType], body: Any, headers: multidict._multidict.CIMultiDictProxy[str], message: str, error_status: str, message_data: dict[str, str])
 2def __init__(self, *, error_code, http_status, throttle_seconds, url, body, headers, message, error_status, message_data):
 3    self.error_code = error_code
 4    self.http_status = http_status
 5    self.throttle_seconds = throttle_seconds
 6    self.url = url
 7    self.body = body
 8    self.headers = headers
 9    self.message = message
10    self.error_status = error_status
11    self.message_data = message_data
12    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: Union[str, yarl.URL, NoneType], body: Any, headers: multidict._multidict.CIMultiDictProxy[str], message: str, error_status: str, message_data: dict[str, str])
 2def __init__(self, *, error_code, throttle_seconds, url, body, headers, message, error_status, message_data):
 3    self.error_code = error_code
 4    self.throttle_seconds = throttle_seconds
 5    self.url = url
 6    self.body = body
 7    self.headers = headers
 8    self.message = message
 9    self.error_status = error_status
10    self.message_data = message_data
11    self.http_status = attr_dict['http_status'].default
12    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.client_reqrep.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: 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(  # noqa: W503
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}"  # noqa: W503
465    )