<jupyter_start><jupyter_text>Steps to getting an Authorization Token1. Register a web application on MyAnimeList as described in https://myanimelist.net/blog.php?eid=8357072. Store your MyAnimeList Client ID and Client Secret in the files `data/mal/mal_authentication/clientid.txt` and `data/mal/mal_authentication/clientsecret.txt`3. run the notebook<jupyter_code>import json
import os
import secrets

import requests

os.chdir("../../data/mal/mal_authentication")
with open("clientid.txt") as f:
    CLIENT_ID = f.read().strip()
with open("clientsecret.txt") as f:
    CLIENT_SECRET = f.read().strip()

# 1. Generate a new Code Verifier / Code Challenge.
def get_new_code_verifier() -> str:
    token = secrets.token_urlsafe(100)
    return token[:128]


# 2. Print the URL needed to authorise your application.
def print_new_authorisation_url(code_challenge: str):
    global CLIENT_ID

    url = f"https://myanimelist.net/v1/oauth2/authorize?response_type=code&client_id={CLIENT_ID}&code_challenge={code_challenge}"
    print(f"Authorise your application by clicking here: {url}\n")
    print(
        f"After pressing 'Allow', it's okay if the page fails to open, you just"
        " need to copy the URL that it tries to redirect you to\n"
    )


# 3. Once you've authorised your application, you will be redirected to the webpage you've
#    specified in the API panel. The URL will contain a parameter named "code" (the Authorisation
#    Code). You need to feed that code to the application.
def generate_new_token(authorisation_code: str, code_verifier: str) -> dict:
    global CLIENT_ID, CLIENT_SECRET

    url = "https://myanimelist.net/v1/oauth2/token"
    data = {
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "code": authorisation_code,
        "code_verifier": code_verifier,
        "grant_type": "authorization_code",
    }

    response = requests.post(url, data)
    response.raise_for_status()  # Check whether the requests contains errors

    token = response.json()
    response.close()
    print("Token generated successfully!")

    with open("token.json", "w") as file:
        json.dump(token, file, indent=4)
        print('Token saved in "token.json"')

    return token


# 4. Test the API by requesting your profile information
def print_user_info(access_token: str):
    url = "https://api.myanimelist.net/v2/users/@me"
    response = requests.get(url, headers={"Authorization": f"Bearer {access_token}"})

    response.raise_for_status()
    user = response.json()
    response.close()

    print(f"\n>>> Greetings {user['name']}! <<<")
code_verifier = code_challenge = get_new_code_verifier()
print_new_authorisation_url(code_challenge)
authorisation_code = input("Copy-paste the Authorisation Code or URL: ").strip()
default_url_prefix = "http://localhost/oauth?code="
if authorisation_code.startswith(default_url_prefix):
    authorisation_code = authorisation_code[len(default_url_prefix) :]
token = generate_new_token(authorisation_code, code_verifier)
print_user_info(token['access_token'])<jupyter_output>>>> Greetings Fro116! <<<
{'fraction_non_alphanumeric': 0.11164736164736165, 'fraction_numerical': 0.009009009009009009, 'mean_word_length': 4.369602763385147, 'pattern_counts': {'":': 6, '<': 10, '<?xml version=': 0, '>': 12, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '448949', 'license': 'MIT', 'n_tokens_mistral': 1021, 'n_tokens_neox': 968, 'n_words': 258, 'path': 'notebooks/API/GenerateToken.ipynb', 'repo_name': 'Fro116/RecommenderSystem', 'size': '3108'}