Library written in Python that wraps Halo Infinite API.

Overview

haloinfinite

Library written in Python that wraps Halo Infinite API.

Before start

It's unofficial, reverse-engineered, neither stable nor production ready Halo Infinite web API.

You need to register an Azure Active Directory application and set a Client Secret for your application.

Credits

Credits to Den Delimarsky for the reverse-engineering. If you want to learn more then check his Halo Infinite Web API blog series. Also you can use his API wrapper written in C#.

Installing

From Pip (recommended)

pip install haloinfinite

From Github

pip install git+https://github.com/ingmferrer/haloinfinite.git

From tar.gz file

Download haloinfinite-X.Y.Z.tar.gz from the Releases page.

pip install haloinfinite-X.Y.Z.tar.gz

Usage

Client instantiation

from haloinfinite.client import HaloInfiniteAPIClient as Client
client = Client(client_id, client_secret, user_token=None, xbox_user_token=None, xsts_xbox_token=None, xsts_halo_token=None, spartan_token=None, clearance_token=None)

OAuth 2.0

Get authorization url

url = client.get_authorization_url(redirect_uri, scope=["Xboxlive.signin", "Xboxlive.offline_access"], state=None)

Exchange the code for an user token

user_token = client.exchange_code(redirect_uri, code)

# print(user_token.data)
{
    "token_type": "bearer",
    "expires_in": 3600,
    "scope": "XboxLive.signin XboxLive.offline_access",
    "access_token": "...",
    "refresh_token": "...",
    "user_id": "...",
}

Refresh user token

user_token = client.refresh_token(redirect_uri, user_token["refresh_token"])

# print(user_token.data)
{
    "token_type": "bearer",
    "expires_in": 3600,
    "scope": "XboxLive.signin XboxLive.offline_access",
    "access_token": "...",
    "refresh_token": "...",
    "user_id": "...",
}

Set user token

client.set_user_token(user_token)

Get xbox user token

xbox_user_token = client.get_xbox_user_token()

# print(xbox_user_token.data)
{
    "IssueInstant": "2022-02-06T01:00:03.6132203Z",
    "NotAfter": "2022-02-20T01:00:03.6132203Z",
    "Token": "...",
    "DisplayClaims": {"xui": [{"uhs": "..."}]},
}

Set xbox user token

client.set_xbox_user_token(token=xbox_user_token)

Get xsts xbox token

xsts_xbox_token = client.get_xsts_xbox_token()

# print(xsts_xbox_token.data)
{
    "IssueInstant": "2022-02-06T01:35:40.7628209Z",
    "NotAfter": "2022-02-06T17:35:40.7628209Z",
    "Token": "...",
    "DisplayClaims": {
        "xui": [
            {
                "gtg": "...",
                "xid": "...",
                "uhs": "...",
                "agg": "Adult",
                "usr": "...",
                "utr": "...",
                "prv": "...",
            }
        ]
    },
}

Set xsts xbox token

client.set_xsts_xbox_token(token=xsts_xbox_token)

Get xsts halo token

xsts_halo_token = client.get_xsts_xbox_token()

# print(xsts_halo_token.data)
{
    "IssueInstant": "2022-02-06T01:12:27.9108457Z",
    "NotAfter": "2022-02-06T05:12:27.9108457Z",
    "Token": "...",
    "DisplayClaims": {"xui": [{"uhs": "..."}]},
}

Set xsts halo token

client.set_xsts_halo_token(token=xsts_halo_token)

Get spartan token

spartan_token = client.get_xsts_xbox_token()

# print(spartan_token.data)
{
    "SpartanToken": "...",
    "ExpiresUtc": {"ISO8601Date": "2022-02-06T05:12:27Z"},
    "TokenDuration": "PT3H34M12.4226916S",
}

Set spartan token

client.set_spartan_token(token=spartan_token)

Get clearance token

clearance_token = client.get_clearance_token()

# print(clearance_token.data)
{
    "FlightConfigurationId": "...",
}

Set clearance token

client.set_clearance_token(token=clearance_id)

Match API

Match privacy

response = client.match.get_match_privacy()

# print(response.data)
{'MatchmadeGames': 1, 'OtherGames': 2}

Match count

response = client.match.get_match_count()

# print(response.data)
{'CustomMatchesPlayedCount': 6, 'MatchesPlayedCount': 885, 'MatchmadeMatchesPlayedCount': 879, 'LocalMatchesPlayedCount': 0}

Match history

response = client.match.get_match_history()

# print(response.data)
{'Count': 25,
 'Links': {},
 'ResultCount': 25,
 'Results': [{'LastTeamId': 0,
              'MatchId': '...',
              'MatchInfo': {'ClearanceId': '...',
                            'Duration': 'PT9M22.8961519S',
                            'EndTime': '2022-02-05T23:30:32.564Z',
                            'GameVariantCategory': 9,
                            'LevelId': '...',
                            'LifecycleMode': 3,
                            'MapVariant': {'AssetId': '...',
                                           'AssetKind': 2,
                                           'VersionId': '...'},
                            'PlayableDuration': 'PT9M22.875S',
                            'Playlist': {'AssetId': '...',
                                         'AssetKind': 3,
                                         'VersionId': '...'},
                            'PlaylistExperience': 5,
                            'PlaylistMapModePair': {'AssetId': '...',
                                                    'AssetKind': 7,
                                                    'VersionId': '...'},
                            'SeasonId': 'Seasons/Season6.json',
                            'StartTime': '2022-02-05T23:20:39.923Z',
                            'TeamScoringEnabled': True,
                            'TeamsEnabled': True,
                            'UgcGameVariant': {'AssetId': '...',
                                               'AssetKind': 6,
                                               'VersionId': '...'}},
              'Outcome': 3,
              'PresentAtEndOfMatch': True,
              'Rank': 6},
              ...
 'Start': 0}

Match stats

response = client.match.get_match_stats(match_id)

# print(response.data)
{'MatchId': '...',
 'MatchInfo': {'ClearanceId': '...',
               'Duration': 'PT9M22.8961519S',
               'EndTime': '2022-02-05T23:30:32.564Z',
               'GameVariantCategory': 9,
               'LevelId': '...',
               'LifecycleMode': 3,
               'MapVariant': {'AssetId': '...',
                              'AssetKind': 2,
                              'VersionId': '...'},
               'PlayableDuration': 'PT9M22.875S',
               'Playlist': {'AssetId': '...',
                            'AssetKind': 3,
                            'VersionId': '...'},
               'PlaylistExperience': 5,
               'PlaylistMapModePair': {'AssetId': '...',
                                       'AssetKind': 7,
                                       'VersionId': '...'},
               'SeasonId': 'Seasons/Season6.json',
               'StartTime': '2022-02-05T23:20:39.923Z',
               'TeamScoringEnabled': True,
               'TeamsEnabled': True,
               'UgcGameVariant': {'AssetId': '...',
                                  'AssetKind': 6,
                                  'VersionId': '...'}},
 'Players': [...],
 'Teams': [...],

Match skill

response = client.match.get_match_skill(match_id, player_id)

# print(response.data)
{'Value': [{'Id': 'xuid(...)',
            'Result': {'Counterfactuals': {'SelfCounterfactuals': {'Deaths': 12.38441050555862,
                                                                   'Kills': 11.805217023995946},
                                           'TierCounterfactuals': {}},
                       'RankRecap': {'PostMatchCsr': {'InitialMeasurementMatches': 0,
                                                      'MeasurementMatchesRemaining': 0,
                                                      'NextSubTier': 0,
                                                      'NextTier': '',
                                                      'NextTierStart': 0,
                                                      'SubTier': 0,
                                                      'Tier': '',
                                                      'TierStart': 0,
                                                      'Value': 0},
                                     'PreMatchCsr': {'InitialMeasurementMatches': 0,
                                                     'MeasurementMatchesRemaining': 0,
                                                     'NextSubTier': 0,
                                                     'NextTier': '',
                                                     'NextTierStart': 0,
                                                     'SubTier': 0,
                                                     'Tier': '',
                                                     'TierStart': 0,
                                                     'Value': 0}},
                       'RankedRewards': None,
                       'StatPerformances': {'Deaths': {'Count': 9,
                                                       'Expected': 12.38441050555862,
                                                       'StdDev': 4.498181792537211},
                                            'Kills': {'Count': 13,
                                                      'Expected': 11.805217023995946,
                                                      'StdDev': 4.750282423640629}},
                       'TeamId': 0,
                       'TeamMmr': 1149.370133486992,
                       'TeamMmrs': {'0': 1149.370133486992,
                                    '1': 1151.942592441846}},
            'ResultCode': 0}]}

Match progression

response = client.match.get_match_progression(match_id)

# print(response.data)
{'ChallengeProgressState': [{'Id': '...',
                             'Path': 'ChallengeContent/ClientChallengeDefinitions/S1CapstoneChallenges/CSamuraiMedalKilljoy.json',
                             'PreviousProgress': 1,
                             'Progress': 3},
                            {'Id': '...',
                             'Path': 'ChallengeContent/ClientChallengeDefinitions/DailyChallenges/PlayNew/d0NPlayB1.json',
                             'PreviousProgress': 0,
                             'Progress': 1}],
 'ClearanceId': '...',
 'RewardId': '...'}

Requirements

  • requests
  • python-dateutil

Tests

  • Not yet

Contributing

We are always grateful for any kind of contribution including but not limited to bug reports, code enhancements, bug fixes, and even functionality suggestions.

You can report any bug you find or suggest new functionality with a new issue.

If you want to add yourself some functionality to the wrapper:

  1. Fork it ( https://github.com/ingmferrer/haloinfinite )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Adds my new feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request
You might also like...
Clubhouse API written in Python. Standalone client included. For reference and education purposes only.
Clubhouse API written in Python. Standalone client included. For reference and education purposes only.

clubhouse-py is originally developed for the sake of interoperability. Standalone client is also created with very basic features, including but not limited to the audio-chat

A GETTR API client written in Python.

GUTTR A GETTR client library written in Python. I rushed to get this out so it's a bit janky. Open an issue if something is broken or missing. Getting

The official wrapper for spyse.com API, written in Python, aimed to help developers build their integrations with Spyse.

Python wrapper for Spyse API The official wrapper for spyse.com API, written in Python, aimed to help developers build their integrations with Spyse.

An API wrapper for convertio.co written in Python.

An API wrapper for convertio.co written in Python.

A simple API wrapper for Discord written in Python.

AIOCord This project is work in progress not for production use A simple asynchronous API wrapper around Discord API written in Python. Inspiration Th

A tool written in Python used to instalock agents in VALORANT using the local API.

Valorant Instalock Tool v2.1.0 by Mr. SOSA A tool written in Python used to instalock agents in VALORANT using the local API. This is NOT a hotkey pro

Python written Rule34 API

Python written Rule34 API

A modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python.
A modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python.

A modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python. Key Features Modern Pythonic API using async and await

A modern,feature-rich, and async ready API wrapper for Discord written in Python

discord.io A modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python. Key Features Modern Pythonic API using asyn

Owner
Miguel Ferrer
Creador de teemu.app y discordea.net
Miguel Ferrer
An advanced api client for python botters.

[ALPHA] pybotters An advanced api client for python botters. 📌 Description pybottersは仮想通貨botter向けのPythonライブラリです。複数取引所に対応した非同期APIクライアントであり、bot開発により素晴ら

261 Dec 31, 2022
Anti Spam/NSFW Telegram Bot Written In Python With Pyrogram.

✨ SpamProtectionRobot ✨ Anti Spam/NSFW Telegram Bot Written In Python With Pyrogram. Requirements Python = 3.7 Install Locally Or On A VPS $ git clon

Akshay Rajput 46 Dec 13, 2022
Nonebot2 简易群管

简易群管 ✨ NoneBot2 简易群管 ✨ _ 踢 改 禁 欢迎issue pr 权限说明:permission=SUPERUSER 安装 💿 pip install nonebot-plugin-admin 导入 📲 在bot.py 导入,语句: nonebot.load_plugin("n

幼稚园园长 74 Dec 22, 2022
OpenSea Bulk Uploader And Trader 100000 NFTs (MAC WINDOWS ANDROID LINUX) Automatically and massively upload and sell your non-fungible tokens on OpenSea using Python Selenium

OpenSea Bulk Uploader And Trader 100000 NFTs (MAC WINDOWS ANDROID LINUX) Automatically and massively upload and sell your non-fungible tokens on OpenS

ERC-7211 3 Mar 24, 2022
A component of BuzzUtilityBot that allows for inter-server communication

A component of BuzzUtilityBot that allows for inter-server communication! Separated due to privacy and ease of inspection concerns

OHaiiBuzzle 2 Oct 11, 2022
DIAL(Did I Alert Lambda?) is a centralised security misconfiguration detection framework which completely runs on AWS Managed services like AWS API Gateway, AWS Event Bridge & AWS Lambda

DIAL(Did I Alert Lambda?) is a centralised security misconfiguration detection framework which completely runs on AWS Managed services like AWS API Gateway, AWS Event Bridge & AWS Lambda

CRED 71 Dec 29, 2022
ResolveURL - Fork of UrlResolver by eldorados, tknorris and jsergio123

ResolveURL Fork of UrlResolver by eldorados, tknorris and jsergio123 I am in no

gujal 60 Jan 03, 2023
CRUD database for python discord bot developers that stores data on discord text channels

Discord Database A CRUD (Create Read Update Delete) database for python Discord bot developers. All data is stored in key-value pairs directly on disc

Ankush Singh 7 Oct 22, 2022
A file-based quote bot written in Python

Let's Write a Python Quote Bot! This repository will get you started with building a quote bot in Python. It's meant to be used along with the Learnin

1 Nov 01, 2021
Python API Client for Close

Close API A convenient Python wrapper for the Close API. API docs: http://developer.close.com Support: Close 56 Nov 30, 2022

A tool written in Python used to instalock agents in VALORANT using the local API.

Valorant Instalock Tool v2.1.0 by Mr. SOSA A tool written in Python used to instalock agents in VALORANT using the local API. This is NOT a hotkey pro

Mr. SOSA 3 Nov 18, 2021
Python written Rule34 API

Python written Rule34 API

1 Nov 11, 2021
OKEX数字货币自动交易python语言SDK

okex-py OKEx数字货币自动交易python语言SDK (非官方) OKEx Cryptocurrency Exchange python SDK (Unofficial) 本项目基于V5 API 使用例子 Example import okex.v5.account_api as acco

43 Dec 01, 2022
Discord RPC for Notion written in Python

Discord RPC for Notion This is a program that allows you to add your Notion workspace activities to your Discord profile. This project is currently un

Thuliumitation 1 Feb 10, 2022
A secure and customizable bot for controlling cross-server announcements and interactions within Discord

DiscordBot A secure and customizable bot for controlling cross-server announcements and interactions within Discord. Within the code of the bot, you c

Jacob Dorfmeister 1 Jan 22, 2022
Generate Heroku-like random names to use in your python applications

HaikunatorPY Generate Heroku-like random names to use in your python applications. Installation pip install haikunator Usage Haikunator is pretty sim

Atrox 116 Nov 15, 2022
universal messaging & notifications api

Pronounced "boat-shahft" What is botschaft? Botschaft is unified messaging & notifications appliance. Want to text yourself when a long-running task c

Tyler M. Kontra 25 Aug 16, 2022
Add members to unlimited telegram channels and groups

Program Features 📌 Coded with Python version 10. 📌 without the need for a proxy. 📌 without the need for a Telegram ID. 📌 Ability to add infinite p

hack4lx 10 Nov 25, 2022
Easy and simple, Telegram Bot to Show alert when some edits a message in Group

Edit-Message-Alert Just a simple bot to show alert when someone edits a message sent by them, Just 17 Lines of Code These codes are for those who incu

Nuhman Pk 6 Dec 15, 2021
Telephus is a connection pooled, low-level client API for Cassandra in Twisted python.

Telephus Son of Heracles who loved Cassandra. He went a little crazy, at one point. One might almost say he was twisted. Description Telephus is a con

Brandon Williams 93 Apr 29, 2021