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
Ivan Telegram Userbot with python

Riviani Ramadhan Ivan-Ubot Pada Dasarnya Ivan-Ubot adalah userbot Telegram modular yang berjalan di Python3 dengan database sqlalchemy. Berbasis Paper

1 Oct 29, 2021
A Powerfull Userbot Telegram PandaX_Userbot, Vc Music Userbot + Bot Manager based Telethon

Support โ˜‘ CREDITS THANKS YOU VERRY MUCH FOR ALL Telethon Pyrogram TeamUltroid TeamUserge CatUserbot pytgcalls Dan Lainnya

22 Dec 25, 2022
Nautobot-custom-jobs - Custom jobs for Nautobot

nautobot-custom-jobs This repo contains custom jobs for Nautobot. Installation P

Dan Peachey 9 Oct 27, 2022
๐Ÿค– Telegram UserBot Untuk Memutar Lagu Dan Video Di Obrolan Suara Telegram.

๐Ÿค– Telegram UserBot Untuk Memutar Lagu Dan Video Di Obrolan Suara Telegram.

Fariz 2 Nov 13, 2021
Generates a coverage badge using coverage.py and the shields.io service.

Welcome to README Coverage Badger ๐Ÿ‘‹ Generates a coverage badge using coverage.py and the shields.io service. Your README file is then updated with th

Victor Miti 10 Dec 06, 2022
A multipurpose bot designed to make Discord better for everyone, written in Python.

Hadum A multipurpose bot that makes Discord better for everyone Features A Fully Functional Moderation component: manage your staff, members and permi

1 Jan 25, 2022
this synchronizes my appearances with my calendar

Josh's Schedule Synchronizer Here's the "problem:" I use a spreadsheet to maintain all my public appearances. I check the spreadsheet as often as poss

Josh Long 2 Oct 18, 2021
"Nesse projeto criei uma automaรงรฃo para abrir as tarefas no Jira em massa pegando de uma determinada fila do Zendesk."

automacao-Zendesk "Nesse projeto criei uma automaรงรฃo para abrir as tarefas no Jira em massa pegando de uma determinada fila do Zendesk." en-us "In thi

tokoyamy 1 Dec 20, 2021
Notflix - Notion / Netflix and IMDb to organise your movie dates. Happy Valentine <3 from 0x1za

Welcome to notflix ๐Ÿ‘‹ This is a project to help organise shows to watch with my

Mwiza Ed' Simbeye 3 Feb 15, 2022
Simple Telegram bot to confess to your crush this Valentine's Day

Simple Telegram bot to confess to your crush this Valentine's Day! Steps pip install python-telegram-bot Register a Telegram bot & get the token by fo

3 Mar 18, 2022
Kyura-Userbot: a modular Telegram userbot that runs in Python3 with a sqlalchemy database

Kyura-Userbot Telegram Kyura-Userbot adalah userbot Telegram modular yang berjal

Kyura 17 Oct 29, 2022
Scheduled Block Checker for Cardano Stakepool Operators

ScheduledBlocks Scheduled Block Checker for Cardano Stakepool Operators Lightweight and Portable Scheduled Blocks Checker for Current Epoch. No cardan

SNAKE (Cardano Stakepool) 4 Oct 18, 2022
WallAlley.bot is an open source and free to use financial discord bot originaly build for WallAlley server's community

WallAlley.bot About WallAlley.bot is an open source and free to use financial discord bot originaly build for WallAlley server's community. All data a

Mohammad KHADDAN 1 Jan 22, 2022
It's a discord.py simulator.

DiscordPySimulator It's a discord.py simulator. โš ๏ธ Things to fix Context As you may know, discord py commands provide the context as the first paramet

Juan Sebastiรกn 11 Oct 24, 2022
Query Amalgamator over StackOverflow and YouTube

QASY Query Amalgamator over StackOverflow and YouTube Decription A software you can use to save your valuable time of googling the errors you encounte

1 Nov 07, 2021
Unofficial Discord Rich Presence for HackTheBox platform

HTBRichPresence Unofficial Discord Rich Presence for HackTheBox platform The project is under lazy development. How to run Install requirements: // I'

Antonio 4 Apr 19, 2022
Visionary-OS: open source discord bot

Visionary-OS Our Visionary open source discord bot. Our goal is to create a discord bot, which is hosted by us, but every member of our community can

8 Jan 27, 2022
discord token grabber scam - eductional purposes only!

Discord-QR-Scam ืชื•ืคืก ืืกื™ืžื•ืŸ ืชืžื•ื ื” ืฉืœ Discord ืขืœ ืื•ื“ื•ืช ืกืงืจื™ืคื˜ Python ืฉื™ื•ืฆืจ ืื•ื˜ื•ืžื˜ื™ืช ืงื•ื“ QR ื”ื•ื ืื” ืฉืœ Nitro ื•ืชื•ืคืก ืืช ืืกื™ืžื•ืŸ ื”ื“ื™ืกืงื•ืจื“ ื‘ืขืช ืกืจื™ืงื”. ื›ืœื™ ื–ื” ืžื“

Amit Pinchasi 0 May 22, 2022
GitHub Usage Report

github-analytics from github_analytics import analyze pr_analysis = analyze.PRAnalyzer( "organization/repo", "organization", "team-name",

Shrivu Shankar 1 Oct 26, 2021
The Python SDK for the BattleshAPI game

BattleshAPy The Python SDK for the BattleshAPI game Installation This library will be eventually going on PyPI, but until then, simply clone or downlo

Christopher 0 Apr 18, 2022