├── .coveragerc ├── .flake8 ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── LICENSE.md ├── SECURITY.md ├── pull_request_template.md └── workflows │ ├── main.yaml │ ├── pull_request.yaml │ ├── refresh_graphql_jsons.yml │ └── sonarcloud.yaml ├── .gitignore ├── .readthedocs.yaml ├── .version ├── Dockerfile ├── README.md ├── docs ├── Makefile ├── assets │ ├── login_flow.png │ ├── login_flow.txt │ └── login_url.png ├── conftest.rst ├── make.bat └── source │ ├── api │ ├── auth │ │ └── auth.rst │ ├── query │ │ └── query.rst │ ├── scraper │ │ └── scraper.rst │ └── utils.rst │ ├── conf.py │ ├── generated │ ├── auth │ │ ├── EnvironmentVariablesManager.BASE_TOKENS.rst │ │ ├── EnvironmentVariablesManager.__init__.rst │ │ ├── EnvironmentVariablesManager.add_token.rst │ │ ├── EnvironmentVariablesManager.get.rst │ │ ├── EnvironmentVariablesManager.get_all.rst │ │ ├── EnvironmentVariablesManager.remove_token.rst │ │ ├── EnvironmentVariablesManager.rst │ │ ├── EnvironmentVariablesManager.token_to_variable.rst │ │ ├── EnvironmentVariablesManager.variable_to_token.rst │ │ ├── GraphQLQueries.__init__.rst │ │ ├── GraphQLQueries.get_hashes.rst │ │ ├── GraphQLQueries.get_query.rst │ │ ├── GraphQLQueries.query.rst │ │ ├── GraphQLQueries.query_body.rst │ │ ├── GraphQLQueries.query_body_hash.rst │ │ ├── GraphQLQueries.query_hash.rst │ │ ├── GraphQLQueries.query_header.rst │ │ ├── GraphQLQueries.rst │ │ ├── NSO.__init__.rst │ │ ├── NSO.g_token_generation_phase_1.rst │ │ ├── NSO.g_token_generation_phase_2.rst │ │ ├── NSO.generate_login_url.rst │ │ ├── NSO.generate_new_state.rst │ │ ├── NSO.generate_new_verifier.rst │ │ ├── NSO.get_bullet_token.rst │ │ ├── NSO.get_ftoken.rst │ │ ├── NSO.get_gtoken.rst │ │ ├── NSO.get_gtoken_request.rst │ │ ├── NSO.get_session_token.rst │ │ ├── NSO.get_user_access_token.rst │ │ ├── NSO.get_user_info.rst │ │ ├── NSO.get_version.rst │ │ ├── NSO.get_web_service_access_token.rst │ │ ├── NSO.new_instance.rst │ │ ├── NSO.parse_npf_uri.rst │ │ ├── NSO.rst │ │ ├── NSO.session_token.rst │ │ ├── NSO.set_new_f_token_function.rst │ │ ├── NSO.splatnet_web_version.rst │ │ ├── NSO.state.rst │ │ ├── NSO.verifier.rst │ │ ├── NSO.version.rst │ │ ├── Token.__init__.rst │ │ ├── Token.__repr__.rst │ │ ├── Token.is_expired.rst │ │ ├── Token.is_valid.rst │ │ ├── Token.rst │ │ ├── Token.time_left.rst │ │ ├── Token.time_left_str.rst │ │ ├── TokenManager.__init__.rst │ │ ├── TokenManager.add_session_token.rst │ │ ├── TokenManager.add_token.rst │ │ ├── TokenManager.data.rst │ │ ├── TokenManager.flag_origin.rst │ │ ├── TokenManager.from_config_file.rst │ │ ├── TokenManager.from_env.rst │ │ ├── TokenManager.from_session_token.rst │ │ ├── TokenManager.from_text_file.rst │ │ ├── TokenManager.generate_all_tokens.rst │ │ ├── TokenManager.generate_bullet_token.rst │ │ ├── TokenManager.generate_gtoken.rst │ │ ├── TokenManager.get.rst │ │ ├── TokenManager.load.rst │ │ ├── TokenManager.origin.rst │ │ ├── TokenManager.rst │ │ ├── TokenManager.save.rst │ │ ├── TokenManager.test_tokens.rst │ │ └── TokenManager.token_is_valid.rst │ ├── query │ │ ├── Config.ACCEPTED_OPTIONS.rst │ │ ├── Config.DEFAULT_OPTIONS.rst │ │ ├── Config.DEPRECATED_OPTIONS.rst │ │ ├── Config.__init__.rst │ │ ├── Config.add_accepted_options.rst │ │ ├── Config.add_default_options.rst │ │ ├── Config.add_deprecated_options.rst │ │ ├── Config.from_env.rst │ │ ├── Config.from_s3s_config.rst │ │ ├── Config.generate_token_manager.rst │ │ ├── Config.get.rst │ │ ├── Config.get_data.rst │ │ ├── Config.get_token.rst │ │ ├── Config.initialize_options.rst │ │ ├── Config.manage_options.rst │ │ ├── Config.remove_accepted_options.rst │ │ ├── Config.remove_default_options.rst │ │ ├── Config.remove_deprecated_options.rst │ │ ├── Config.rst │ │ ├── Config.save.rst │ │ ├── JSONParser.__eq__.rst │ │ ├── JSONParser.__init__.rst │ │ ├── JSONParser.__repr__.rst │ │ ├── JSONParser.automatic_type_conversion.rst │ │ ├── JSONParser.from_csv.rst │ │ ├── JSONParser.from_gzipped_json.rst │ │ ├── JSONParser.from_json.rst │ │ ├── JSONParser.from_parquet.rst │ │ ├── JSONParser.remove_columns.rst │ │ ├── JSONParser.remove_url_columns.rst │ │ ├── JSONParser.rst │ │ ├── JSONParser.to_csv.rst │ │ ├── JSONParser.to_gzipped_json.rst │ │ ├── JSONParser.to_json.rst │ │ ├── JSONParser.to_parquet.rst │ │ ├── QueryHandler.__init__.rst │ │ ├── QueryHandler.from_config_file.rst │ │ ├── QueryHandler.from_env.rst │ │ ├── QueryHandler.from_s3s_config.rst │ │ ├── QueryHandler.from_session_token.rst │ │ ├── QueryHandler.generate_session_token_url.rst │ │ ├── QueryHandler.query.rst │ │ ├── QueryHandler.query_hash.rst │ │ ├── QueryHandler.rst │ │ ├── QueryResponse.__eq__.rst │ │ ├── QueryResponse.__getitem__.rst │ │ ├── QueryResponse.__init__.rst │ │ ├── QueryResponse.__iter__.rst │ │ ├── QueryResponse.__repr__.rst │ │ ├── QueryResponse.apply.rst │ │ ├── QueryResponse.data.rst │ │ ├── QueryResponse.get.rst │ │ ├── QueryResponse.items.rst │ │ ├── QueryResponse.keys.rst │ │ ├── QueryResponse.match_partial_path.rst │ │ ├── QueryResponse.metadata.rst │ │ ├── QueryResponse.parse_json.rst │ │ ├── QueryResponse.query.rst │ │ ├── QueryResponse.rst │ │ ├── QueryResponse.show.rst │ │ ├── QueryResponse.timestamp.rst │ │ ├── QueryResponse.timestamp_raw.rst │ │ └── QueryResponse.values.rst │ └── scraper │ │ ├── QueryMap.ANARCHY.rst │ │ ├── QueryMap.ANARCHY_DETAIL.rst │ │ ├── QueryMap.BANKARA_BATTLE_HISTORIES.rst │ │ ├── QueryMap.BANKARA_BATTLE_HISTORIES_REFETCH.rst │ │ ├── QueryMap.BATTLE_HISTORY_CURRENT_PLAYER.rst │ │ ├── QueryMap.CATALOG.rst │ │ ├── QueryMap.CHECKIN.rst │ │ ├── QueryMap.CHECKIN_QR.rst │ │ ├── QueryMap.CONFIGURE_ANALYTICS.rst │ │ ├── QueryMap.COOP.rst │ │ ├── QueryMap.COOP_DETAIL.rst │ │ ├── QueryMap.COOP_HISTORY.rst │ │ ├── QueryMap.COOP_HISTORY_DETAIL.rst │ │ ├── QueryMap.COOP_HISTORY_DETAIL_REFETCH.rst │ │ ├── QueryMap.COOP_PAGER_LATEST_COOP.rst │ │ ├── QueryMap.COOP_RECORD.rst │ │ ├── QueryMap.COOP_RECORD_BIG_RUN_RECORD_CONTAINER_PAGINATION.rst │ │ ├── QueryMap.COOP_RECORD_REFETCH.rst │ │ ├── QueryMap.CREATE_MY_OUTFIT_MUTATION.rst │ │ ├── QueryMap.DETAIL_FEST_RECORD_DETAIL.rst │ │ ├── QueryMap.DETAIL_FEST_REFETCH.rst │ │ ├── QueryMap.DETAIL_FEST_VOTING_STATUS_REFETCH.rst │ │ ├── QueryMap.DETAIL_RANKING.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_AR_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_CL_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_GL_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_LF_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_X_RANKING_AR_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_X_RANKING_CL_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_X_RANKING_GL_REFETCH.rst │ │ ├── QueryMap.DETAIL_TAB_VIEW_X_RANKING_LF_REFETCH.rst │ │ ├── QueryMap.DETAIL_VOTING_STATUS.rst │ │ ├── QueryMap.DOWNLOAD_SEARCH_REPLAY.rst │ │ ├── QueryMap.FEST_RECORD.rst │ │ ├── QueryMap.FEST_RECORD_REFETCH.rst │ │ ├── QueryMap.FRIEND_LIST.rst │ │ ├── QueryMap.FRIEND_LIST_REFETCH.rst │ │ ├── QueryMap.GESOTOWN.rst │ │ ├── QueryMap.GESOTOWN_REFETCH.rst │ │ ├── QueryMap.HERO_HISTORY.rst │ │ ├── QueryMap.HERO_HISTORY_REFETCH.rst │ │ ├── QueryMap.HISTORY_RECORD.rst │ │ ├── QueryMap.HISTORY_RECORD_REFETCH.rst │ │ ├── QueryMap.HOME.rst │ │ ├── QueryMap.JOURNEY.rst │ │ ├── QueryMap.JOURNEY_CHALLENGE_DETAIL.rst │ │ ├── QueryMap.JOURNEY_CHALLENGE_DETAIL_REFETCH.rst │ │ ├── QueryMap.JOURNEY_REFETCH.rst │ │ ├── QueryMap.LATEST.rst │ │ ├── QueryMap.LATEST_BATTLE_HISTORIES.rst │ │ ├── QueryMap.LATEST_BATTLE_HISTORIES_REFETCH.rst │ │ ├── QueryMap.LATEST_DETAIL.rst │ │ ├── QueryMap.MY_OUTFITS.rst │ │ ├── QueryMap.MY_OUTFITS_DETAIL.rst │ │ ├── QueryMap.MY_OUTFITS_REFETCH.rst │ │ ├── QueryMap.MY_OUTFIT_COMMON_DATA_EQUIPMENTS.rst │ │ ├── QueryMap.MY_OUTFIT_COMMON_DATA_FILTERING_CONDITION.rst │ │ ├── QueryMap.PAGER_LATEST_VS_DETAIL.rst │ │ ├── QueryMap.PAGER_UPDATE_BATTLE_HISTORIES_BY_VS_MODE.rst │ │ ├── QueryMap.PHOTO_ALBUM.rst │ │ ├── QueryMap.PHOTO_ALBUM_REFETCH.rst │ │ ├── QueryMap.PRIVATE.rst │ │ ├── QueryMap.PRIVATE_BATTLE_HISTORIES.rst │ │ ├── QueryMap.PRIVATE_BATTLE_HISTORIES_REFETCH.rst │ │ ├── QueryMap.PRIVATE_DETAIL.rst │ │ ├── QueryMap.RANKING_HOLDERS_FEST_TEAM_RANKING_HOLDERS_PAGINATION.rst │ │ ├── QueryMap.REFETCHABLE_COOP_HISTORY_COOP_RESULT.rst │ │ ├── QueryMap.REGULAR.rst │ │ ├── QueryMap.REGULAR_BATTLE_HISTORIES.rst │ │ ├── QueryMap.REGULAR_BATTLE_HISTORIES_REFETCH.rst │ │ ├── QueryMap.REGULAR_DETAIL.rst │ │ ├── QueryMap.REPLAY.rst │ │ ├── QueryMap.REPLAY_MODAL_RESERVE_REPLAY_DOWNLOAD_MUTATION.rst │ │ ├── QueryMap.REPLAY_UPLOADED_REPLAY_LIST_REFETCH.rst │ │ ├── QueryMap.SALE_GEAR_DETAIL.rst │ │ ├── QueryMap.SALE_GEAR_DETAIL_ORDER_GESOTOWN_GEAR_MUTATION.rst │ │ ├── QueryMap.SALMON.rst │ │ ├── QueryMap.SALMON_DETAIL.rst │ │ ├── QueryMap.SALMON_RUN.rst │ │ ├── QueryMap.SETTING.rst │ │ ├── QueryMap.STAGE_RECORD.rst │ │ ├── QueryMap.STAGE_RECORDS_REFETCH.rst │ │ ├── QueryMap.STAGE_SCHEDULE.rst │ │ ├── QueryMap.SUPPORT_BUTTON_SUPPORT_CHALLENGE_MUTATION.rst │ │ ├── QueryMap.TURF.rst │ │ ├── QueryMap.TURF_DETAIL.rst │ │ ├── QueryMap.UPDATE_MY_OUTFIT_MUTATION.rst │ │ ├── QueryMap.USE_CURRENT_FEST.rst │ │ ├── QueryMap.VOTES_UPDATE_FEST_VOTE_MUTATION.rst │ │ ├── QueryMap.VS_DETAIL.rst │ │ ├── QueryMap.VS_HISTORY_DETAIL.rst │ │ ├── QueryMap.VS_HISTORY_DETAIL_PAGER_REFETCH.rst │ │ ├── QueryMap.WEAPON_RECORD.rst │ │ ├── QueryMap.WEAPON_RECORDS_REFETCH.rst │ │ ├── QueryMap.XBATTLE.rst │ │ ├── QueryMap.XBATTLE_DETAIL.rst │ │ ├── QueryMap.X_BATTLE_HISTORIES.rst │ │ ├── QueryMap.X_BATTLE_HISTORIES_REFETCH.rst │ │ ├── QueryMap.X_DETAIL.rst │ │ ├── QueryMap.X_RANKING.rst │ │ ├── QueryMap.X_RANKING_DETAIL.rst │ │ ├── QueryMap.X_RANKING_DETAIL_REFETCH.rst │ │ ├── QueryMap.X_RANKING_REFETCH.rst │ │ ├── QueryMap.get.rst │ │ ├── QueryMap.rst │ │ ├── SplatNet_Scraper.__init__.rst │ │ ├── SplatNet_Scraper.from_config_file.rst │ │ ├── SplatNet_Scraper.from_env.rst │ │ ├── SplatNet_Scraper.from_s3s_config.rst │ │ ├── SplatNet_Scraper.from_session_token.rst │ │ ├── SplatNet_Scraper.get_vs_battles.rst │ │ └── SplatNet_Scraper.rst │ ├── index.rst │ └── misc │ ├── contributing.rst │ ├── login_flow.rst │ ├── queries.rst │ ├── quickstart.rst │ └── session_token.rst ├── examples ├── .splatnet3_scraper_example └── x_rank_scraper.py ├── misc └── parse_api_values.py ├── poetry.lock ├── pyproject.toml ├── reports ├── coverage │ └── coverage-badge.svg ├── flake8 │ ├── back.svg │ ├── file.svg │ ├── flake8-badge.svg │ └── flake8stats.txt └── junit │ ├── assets │ └── style.css │ ├── junit.xml │ ├── report.html │ └── test-badge.svg ├── sonar-project.properties ├── src └── splatnet3_scraper │ ├── __init__.py │ ├── auth │ ├── __init__.py │ ├── exceptions.py │ ├── graph_ql_queries.py │ ├── nso.py │ └── tokens │ │ ├── __init__.py │ │ ├── constructor.py │ │ ├── environment_manager.py │ │ ├── keychain.py │ │ ├── manager.py │ │ ├── regenerator.py │ │ ├── token_typing.py │ │ └── tokens.py │ ├── constants.py │ ├── query │ ├── __init__.py │ ├── config │ │ ├── __init__.py │ │ ├── callbacks.py │ │ ├── config.py │ │ ├── config_option.py │ │ └── config_option_handler.py │ ├── handler.py │ ├── json_parser.py │ └── responses.py │ ├── scraper │ ├── __init__.py │ ├── main.py │ └── query_map.py │ ├── splatnet3_webview_data.json │ ├── tournament_webview_data.json │ └── utils │ ├── __init__.py │ ├── hash_data.py │ ├── json_helpers.py │ └── retry.py └── tests ├── __init__.py ├── auth ├── __init__.py ├── test_environment_manager.py ├── test_graphql_queries.py ├── test_nso.py └── tokens │ ├── __init__.py │ ├── test_constructor.py │ ├── test_keychain.py │ ├── test_manager.py │ ├── test_regenerator.py │ └── test_tokens.py ├── conftest.py ├── fixtures ├── __init__.py ├── config.py ├── config_files │ ├── .all │ ├── .expected_all │ ├── .extra_tokens │ ├── .no_data │ ├── .no_tokens_section │ ├── .valid │ ├── .valid_with_ftoken │ ├── .valid_with_ftoken_list │ ├── __init__.py │ └── s3sconfig.txt ├── constants.py ├── json.py ├── linear_json.csv └── linear_json_with_commas.csv ├── mock.py ├── query ├── __init__.py ├── configuration │ ├── __init__.py │ ├── test_callbacks.py │ ├── test_config.py │ ├── test_config_option.py │ └── test_config_option_handler.py ├── test_json_parser.py ├── test_query_response.py └── test_queryhandler.py ├── scraper ├── __init__.py ├── test_main.py └── test_query_map.py ├── test_misc.py └── test_utils.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | exclude_lines = 3 | pragma: not covered 4 | @overload 5 | omit = 6 | examples/* 7 | docs/* -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 80 3 | extend-ignore = E203 4 | per-file-ignores = 5 | __init__.py:F401, E402 6 | tests\*:DAR101, DAR201, F401 7 | 8 | [darglint] 9 | docstring_style = google 10 | strictness = full 11 | indentation = 4 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Ignore HTML files 5 | *.html linguist-detectable=false 6 | *.ipynb linguist-detectable=false 7 | *.css linguist-detectable=false -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] - " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Prerequisites 11 | 12 | * [ ] Have you checked the [README](https://github.com/cesaregarza/SplatNet3_Scraper/blob/main/README.md) for your issue? 13 | * [ ] Have you checked the [documentation](https://splatnet3-scraper.readthedocs.io/en/latest/index.html) for your issue? 14 | * [ ] Have you searched the existing issues to see if your issue is already reported? 15 | 16 | ### SplatNet3 Scraper Issue 17 | 18 | **Description:** 19 | Please provide a clear and concise description of the issue you are facing. 20 | 21 | **Environment:** 22 | - SplatNet3 Scraper version (e.g. v1.0.0): 23 | - Operating System (e.g. Linux, Windows, macOS): 24 | - Python version (e.g. 3.10.0): 25 | - Are you using a virtual environment? (Yes/No): 26 | 27 | **To Reproduce:** 28 | Please provide steps to reproduce the issue: 29 | 1. First step... 30 | 2. Second step... 31 | 3. ... 32 | 33 | **Expected behavior:** 34 | Please provide a clear and concise description of what you expected to happen. 35 | 36 | **Screenshots:** 37 | If applicable, add screenshots to help explain your issue. 38 | 39 | **Logs:** 40 | Please provide any relevant log output or error messages. 41 | 42 | **Additional context:** 43 | Add any other context about the issue here. 44 | 45 | ### Possible Solution 46 | If you have any suggestions or ideas for a fix, please include them here. 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE] - " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Prerequisites 11 | 12 | * [ ] Do you understand the scope of the project? 13 | * [ ] Have you checked the [README](https://github.com/cesaregarza/SplatNet3_Scraper/blob/main/README.md) for your feature request? 14 | * [ ] Have you checked the [documentation](https://splatnet3-scraper.readthedocs.io/en/latest/index.html) for your feature request? 15 | * [ ] Have you searched the existing issues to see if your feature request is already proposed? 16 | 17 | ### SplatNet3 Scraper Feature Request 18 | 19 | **Is your feature request related to a problem? Please describe:** 20 | A clear and concise description of what the problem is. For example: "I'm always frustrated when [...]" 21 | 22 | **Describe the solution you'd like:** 23 | A clear and concise description of what you want to happen. 24 | 25 | **Describe alternatives you've considered:** 26 | A clear and concise description of any alternative solutions or features you've considered. 27 | 28 | **Additional context:** 29 | Add any other context, screenshots, or mockups about the feature request here. 30 | 31 | ### Priority 32 | How important is this feature to you, and why? 33 | - [ ] Low: This is a nice-to-have feature, but not critical. 34 | - [ ] Medium: This feature would improve the user experience or project efficiency. 35 | - [ ] High: This feature is crucial and should be prioritized. 36 | 37 | ### Dependencies 38 | Please note that additional dependencies for the core library will be rejected immediately. If you are suggesting a dependency to be added as an extra, please provide an extremely good argument for its inclusion. 39 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security Policy 2 | 3 | ### Supported Versions 4 | 5 | We are committed to ensuring the security of the SplatNet3 Scraper project. This security policy outlines the supported versions for security updates. 6 | 7 | #### Before 1.0.0 8 | 9 | For versions of SplatNet3 Scraper that are not yet at 1.0.0, we only provide security updates for the latest minor version. 10 | 11 | | Version | Supported | 12 | | ------- | ------------------ | 13 | | < 1.0.0 | :white_check_mark: (latest minor version only) | 14 | 15 | #### After 1.0.0 16 | 17 | For versions of SplatNet3 Scraper that are 1.0.0 or greater, we provide security updates for the last two minor versions. 18 | 19 | | Version | Supported | 20 | | ------- | ------------------ | 21 | | 1.x | :white_check_mark: (last two minor versions) | 22 | 23 | ### Reporting a Vulnerability 24 | 25 | If you discover a vulnerability in the SplatNet3 Scraper project, please **do not** open a public issue. Instead, follow these steps: 26 | 27 | 1. Email the project maintainers at [cesar@cegarza.com](mailto:cesar@cegarza.com) with the details of the vulnerability. 28 | 2. Include the affected versions and any possible solutions or workarounds. 29 | 3. Wait for a response from the maintainers. They will acknowledge your email and provide an expected timeline for a fix or further investigation. 30 | 31 | We appreciate your help in keeping the SplatNet3 Scraper project secure. 32 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | Please provide a clear and concise description of the changes implemented in this pull request. 4 | 5 | Fixes #(issue_number) _(if applicable)_ 6 | 7 | ### Type of Change 8 | 9 | Please select the type of change that applies to this pull request: 10 | 11 | - [ ] Bug fix (non-breaking change which fixes an issue) 12 | - [ ] New feature (non-breaking change which adds functionality) 13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 14 | - [ ] This change requires a documentation update 15 | - [ ] Code optimization 16 | - [ ] Refactoring (no functional changes, no API changes) 17 | 18 | ### Checklist 19 | 20 | Please review the following checklist before submitting your pull request: 21 | 22 | - [ ] I have checked the [README](https://github.com/cesaregarza/SplatNet3_Scraper/blob/main/README.md) for my changes. 23 | - [ ] I have checked the [documentation](https://splatnet3-scraper.readthedocs.io/en/latest/index.html) for my changes (if applicable). 24 | - [ ] I have performed a self-review of my own code. 25 | - [ ] I have commented my code, particularly in hard-to-understand areas. 26 | - [ ] My changes generate no new warnings. 27 | - [ ] I have added tests that prove my fix is effective or that my feature works. 28 | - [ ] New and existing unit tests pass locally with my changes. 29 | - [ ] Any dependent changes have been merged and published in downstream modules (if applicable). 30 | 31 | ### Additional Context 32 | 33 | Add any other context or screenshots about the pull request here. 34 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yaml: -------------------------------------------------------------------------------- 1 | name: Pull Request Checks 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | - develop 8 | 9 | jobs: 10 | build-and-test: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python_image: ["python:3.10-slim", "python:3.11-slim"] 15 | env: 16 | default_image: "python:3.10-slim" 17 | temp_build_version: "0.0.0" 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v3 22 | 23 | - name: Check for changes 24 | id: check_changes 25 | run: | 26 | git fetch origin ${{ github.base_ref }} 27 | CHANGES=$(git diff --name-only origin/${{ github.base_ref }}..${{ github.sha }} -- 'src/') 28 | if [ -n "$CHANGES" ]; then 29 | echo "Changes detected in src/ directory" 30 | echo "has_changes=true" >> $GITHUB_OUTPUT 31 | else 32 | echo "No changes detected in src/ directory" 33 | echo "has_changes=false" >> $GITHUB_OUTPUT 34 | fi 35 | 36 | - name: Cache Poetry Dependencies 37 | uses: actions/cache@v2 38 | with: 39 | path: ~/.cache/pypoetry 40 | key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }} 41 | restore-keys: | 42 | ${{ runner.os }}-poetry- 43 | 44 | - name: Build and Test 45 | if: steps.check_changes.outputs.has_changes == 'true' 46 | run: | 47 | docker build \ 48 | --build-arg PYTHON_IMAGE=${{ matrix.python_image }} \ 49 | --build-arg BUILD_VERSION=${{ env.temp_build_version }} \ 50 | --target test \ 51 | --tag my-image:PR-${{ github.run_number }} \ 52 | . 53 | docker run --name test-container my-image:PR-${{ github.run_number }} 54 | 55 | - name: Cleanup 56 | run: | 57 | docker rmi my-image:PR-${{ github.run_number }} --force 58 | rm -rf temp-dist 59 | -------------------------------------------------------------------------------- /.github/workflows/refresh_graphql_jsons.yml: -------------------------------------------------------------------------------- 1 | name: Update query hashes 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '30 * * * *' 7 | 8 | env: 9 | PR_TITLE: Update query hashes 10 | BASE_BRANCH: develop 11 | BRANCH_NAME: update-query-hashes 12 | GITHUB_TOKEN: ${{ secrets.CI_SN3S_TOKEN }} 13 | 14 | jobs: 15 | check-and-create-pr: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v3 21 | with: 22 | ref: ${{ env.BASE_BRANCH }} 23 | 24 | - name: Set up Python 25 | uses: actions/setup-python@v4 26 | with: 27 | python-version: '3.x' 28 | 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install requests 33 | 34 | - name: Run parse_api_values.py script 35 | env: 36 | GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }} 37 | run: python misc/parse_api_values.py 38 | 39 | - name: Create PR 40 | uses: peter-evans/create-pull-request@v6 41 | with: 42 | title: ${{ env.PR_TITLE }} 43 | commit-message: ${{ env.PR_TITLE }} 44 | branch: ${{ env.BRANCH_NAME }} 45 | base: ${{ env.BASE_BRANCH }} 46 | body: ${{ env.PR_TITLE }} 47 | delete-branch: true -------------------------------------------------------------------------------- /.github/workflows/sonarcloud.yaml: -------------------------------------------------------------------------------- 1 | name: SonarCloud Scan 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | jobs: 9 | sonarcloud: 10 | name: SonarCloud 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python-version: ["3.10", "3.11"] 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 19 | - name: Setup Python 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: ${{ matrix.python-version }} 23 | - name: Install poetry 24 | run: | 25 | curl -sSL https://install.python-poetry.org | python3 - 26 | 27 | - name: Install dependencies 28 | run: | 29 | poetry install -E parquet 30 | 31 | - name: Coverage 32 | run: | 33 | poetry run coverage run -m pytest -rap --junitxml coverage.xml 34 | poetry run coverage xml -i 35 | - name: SonarCloud Scan 36 | uses: SonarSource/sonarcloud-github-action@master 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 39 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 105 | __pypackages__/ 106 | 107 | # Celery stuff 108 | celerybeat-schedule 109 | celerybeat.pid 110 | 111 | # SageMath parsed files 112 | *.sage.py 113 | 114 | # Environments 115 | .env 116 | .venv 117 | env/ 118 | venv/ 119 | ENV/ 120 | env.bak/ 121 | venv.bak/ 122 | 123 | # Spyder project settings 124 | .spyderproject 125 | .spyproject 126 | 127 | # Rope project settings 128 | .ropeproject 129 | 130 | # mkdocs documentation 131 | /site 132 | 133 | # mypy 134 | .mypy_cache/ 135 | .dmypy.json 136 | dmypy.json 137 | 138 | # Pyre type checker 139 | .pyre/ 140 | 141 | # pytype static type analyzer 142 | .pytype/ 143 | 144 | # Cython debug symbols 145 | cython_debug/ 146 | 147 | test*.ipynb 148 | test.py 149 | .vscode/settings.json 150 | input_files 151 | !tests/input_files 152 | *.json 153 | !tests/input_files/*.json 154 | !splatnet3_webview_data.json 155 | !tournament_webview_data.json 156 | *.html 157 | .python-version 158 | *.sh 159 | 160 | # splatnet3_scraper files 161 | .splatnet3_scraper 162 | tokens.ini 163 | *.csv 164 | *.parquet 165 | *.gz 166 | 167 | # Extra goodies 168 | !tests/fixtures/*.csv 169 | !reports/junit/*.html 170 | reports/flake8/*.css -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | version: 2 3 | 4 | # Set the version of Python and other tools you might need 5 | build: 6 | os: "ubuntu-22.04" 7 | tools: 8 | python: "3.10" 9 | jobs: 10 | post_create_environment: 11 | - pip install poetry 12 | - poetry config virtualenvs.create false 13 | post_install: 14 | - poetry install --only docs 15 | 16 | # Build documentation in the docs/ directory with Sphinx 17 | sphinx: 18 | configuration: docs/source/conf.py -------------------------------------------------------------------------------- /.version: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ############################### 2 | # Base Image # 3 | ############################### 4 | ARG BASE_IMAGE=python:3.10-slim 5 | 6 | FROM $BASE_IMAGE AS base 7 | 8 | WORKDIR /app 9 | 10 | ENV POETRY_HOME="/opt/poetry" \ 11 | POETRY_VIRTUALENVS_CREATE=false \ 12 | POETRY_VIRTUALENVS_IN_PROJECT=false \ 13 | POETRY_NO_INTERACTION=1 14 | ENV PATH="$PATH:$POETRY_HOME/bin" 15 | 16 | # Install dependencies 17 | RUN apt-get update && apt-get install -y \ 18 | curl \ 19 | gcc \ 20 | make \ 21 | && rm -rf /var/lib/apt/lists/* 22 | 23 | # Install poetry 24 | RUN curl -sSL https://install.python-poetry.org | python3 - 25 | 26 | RUN poetry config virtualenvs.create false 27 | 28 | ############################### 29 | # Install Dependencies # 30 | ############################### 31 | FROM base AS dependencies 32 | 33 | COPY pyproject.toml poetry.lock ./ 34 | RUN poetry install --no-root 35 | 36 | ############################### 37 | # Build Image # 38 | ############################### 39 | FROM dependencies AS build 40 | 41 | ARG BUILD_VERSION 42 | 43 | COPY . /app/ 44 | 45 | # Build the application 46 | RUN poetry version $BUILD_VERSION && \ 47 | poetry build 48 | 49 | ############################### 50 | # Test Image # 51 | ############################### 52 | FROM build AS test 53 | 54 | RUN poetry install --extras "parquet" && \ 55 | poetry update 56 | 57 | RUN J_PATH=reports/junit \ 58 | C_PATH=reports/coverage \ 59 | F_PATH=reports/flake8 && \ 60 | # Run tests with coverage 61 | poetry run coverage run -m pytest --junitxml=$J_PATH/junit.xml --html=${J_PATH}/report.html -k . && \ 62 | poetry run coverage xml -o $C_PATH/coverage.xml --omit="app/tests/*" && \ 63 | poetry run coverage html -d $C_PATH/htmlcov --omit="app/tests/*" && \ 64 | # Generate badges 65 | poetry run genbadge tests -o $J_PATH/test-badge.svg && \ 66 | poetry run genbadge coverage -o $C_PATH/coverage-badge.svg && \ 67 | # Mypy checks 68 | poetry run mypy . && \ 69 | # Flake8 checks 70 | poetry run flake8 src/ --format=html --htmldir ${F_PATH} --statistics --tee --output-file ${F_PATH}/flake8stats.txt && \ 71 | poetry run genbadge flake8 -i $F_PATH/flake8stats.txt -o $F_PATH/flake8-badge.svg 72 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/assets/login_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/docs/assets/login_flow.png -------------------------------------------------------------------------------- /docs/assets/login_flow.txt: -------------------------------------------------------------------------------- 1 | This is a sequence diagram of the authentication process of SplatNet 3. It uses 2 | PlantUML, which is a text-based diagramming tool. The diagram can be viewed 3 | online at PlantUML's website. 4 | @startuml 5 | participant "User" as U #1E90FF 6 | participant "Nintendo Login Server" as NLS #B22222 7 | participant "Nintendo Connect API" as NCA #B22222 8 | participant "imink API" as im #C71585 9 | participant "SplatNet 3" as SN3 #228B22 10 | 11 | autonumber 1 12 | group Session Token 13 | U -[#1E90FF]> U : Generate Session Token Verifier 14 | group Session Token Code 15 | U -[#1E90FF]> NLS : Session Token Request 16 | NLS --[#B22222]> U : Login Page URL 17 | U -[#1E90FF]> NLS : Login 18 | NLS --[#B22222]> U : Session Token Code 19 | end 20 | U -[#1E90FF]> NCA : Session Token Code 21 | autonumber 6 22 | U -[#1E90FF]> NCA : Session Token Verifier 23 | NCA --[#B22222]> U : Session Token 24 | end 25 | group GameWebToken (GToken) 26 | group Web API Server Credential Access Token 27 | U -[#1E90FF]> NCA : Session Token 28 | NCA --[#B22222]> U : User Access Token 29 | autonumber 9 30 | NCA --[#B22222]> U : ID Token 31 | group User Data 32 | U -[#1E90FF]> NCA : User Access Token 33 | NCA --[#B22222]> U : User Data (Birthday, Language, Country) 34 | autonumber 11 35 | NCA --[#B22222]> U : Nintendo Account ID 36 | end 37 | U -[#1E90FF]> im : ID Token 38 | autonumber 12 39 | U -[#1E90FF]> im : Nintendo Account ID 40 | im --[#C71585]> U : F Token (ID Token) 41 | autonumber 13 42 | im --[#C71585]> U : Timestamp 43 | autonumber 13 44 | im --[#C71585]> U : Request ID 45 | U -[#1E90FF]> NCA : F Token (ID Token) 46 | autonumber 14 47 | U -[#1E90FF]> NCA : Timestamp 48 | autonumber 14 49 | U -[#1E90FF]> NCA : Request ID 50 | autonumber 14 51 | U -[#1E90FF]> NCA : User Data (Birthday, Language, Country) 52 | autonumber 14 53 | U -[#1E90FF]> NCA : ID Token 54 | NCA --[#B22222]> U : Web API Server Credential Access Token 55 | autonumber 15 56 | NCA --[#B22222]> U : Coral User ID 57 | end 58 | group GToken 59 | U -[#1E90FF]> im : Web API Server Credential Access Token 60 | autonumber 16 61 | U -[#1E90FF]> im : Nintendo Account ID 62 | autonumber 16 63 | U -[#1E90FF]> im : Coral User ID 64 | im --[#C71585]> U : F Token (Web API Server Credential Access Token) 65 | autonumber 17 66 | im --[#C71585]> U : Timestamp 67 | autonumber 17 68 | im --[#C71585]> U : Request ID 69 | U -[#1E90FF]> NCA : F Token (Web API Server Credential Access Token) 70 | autonumber 18 71 | U -[#1E90FF]> NCA : Timestamp 72 | autonumber 18 73 | U -[#1E90FF]> NCA : Request ID 74 | autonumber 18 75 | U -[#1E90FF]> NCA : Web API Server Credential Access Token 76 | NCA --[#B22222]> U : GameWebToken 77 | end 78 | end 79 | group Bullet Token 80 | U -[#1E90FF]> SN3 : GameWebToken 81 | autonumber 20 82 | U -[#1E90FF]> SN3 : User Data (Birthday, Language, Country) 83 | SN3 --[#228B22]> U : Bullet Token 84 | end 85 | group Query 86 | U -[#1E90FF]> SN3 : Bullet Token 87 | autonumber 22 88 | U -[#1E90FF]> SN3 : Query 89 | SN3 --[#228B22]> U : Response 90 | end 91 | @enduml -------------------------------------------------------------------------------- /docs/assets/login_url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/docs/assets/login_url.png -------------------------------------------------------------------------------- /docs/conftest.rst: -------------------------------------------------------------------------------- 1 | conftest module 2 | =============== 3 | 4 | .. automodule:: conftest 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/source/api/auth/auth.rst: -------------------------------------------------------------------------------- 1 | Auth Module 2 | ============ 3 | 4 | The auth module is a low-level interface to the SplatNet 3 API. It provides 5 | three main classes and a helper class. 6 | 7 | The :class:`NSO` class contains the logic for authenticating with Nintendo's 8 | servers and obtaining the right access tokens. It generates the necessary 9 | headers, bodies, and cookies for the requests to the SplatNet 3 API. It provides 10 | methods to generate the ``gtoken`` and the ``bullet_token``. It also provides 11 | the option to change the method that is used to generate the ``ftoken``. This 12 | is useful if you wish to use a different method to generate the ``ftoken`` than 13 | querying a third-party website running an emulated version of the Nintendo 14 | Switch Online app. 15 | 16 | The :class:`TokenManager` class provides an interface to store, retrieve, and 17 | generate the tokens that are required to make requests to the SplatNet 3 API. 18 | The :class:`Token` class is a helper class that is used by the 19 | :class:`TokenManager` class to store the tokens alongside their ``token_type``. 20 | 21 | The :class:`GraphQLQueries` class contains the GraphQL queries that are used 22 | to query the SplatNet 3 API. It provides methods to generate the GraphQL query, 23 | as well as a method to obtain the ``query_hash`` that is required to make the 24 | request through a hashmap of the query names to their ``query_hash``. 25 | 26 | For more information on the login process, see the :doc:`../../misc/login_flow` 27 | page. 28 | 29 | Submodules 30 | ---------- 31 | 32 | .. python-apigen-entity-summary:: splatnet3_scraper.auth.NSO 33 | 34 | .. python-apigen-entity-summary:: splatnet3_scraper.auth.TokenManager 35 | 36 | .. python-apigen-entity-summary:: splatnet3_scraper.auth.GraphQLQueries 37 | 38 | .. python-apigen-entity-summary:: splatnet3_scraper.auth.EnvironmentVariablesManager 39 | 40 | .. python-apigen-entity-summary:: splatnet3_scraper.auth.Token -------------------------------------------------------------------------------- /docs/source/api/query/query.rst: -------------------------------------------------------------------------------- 1 | Query Module 2 | ============ 3 | 4 | The query module is a high-level interface to the SplatNet 3 API. It provides 5 | a simple interface for making queries to the API, and automatically handles 6 | authentication, session management, and token refreshing. 7 | 8 | The main class in this module is :class:`QueryHandler`, which is used to make 9 | queries to the API. It is designed to be as easy to use as possible, and its 10 | primary public method is :meth:`QueryHandler.query`, which takes a query string 11 | and, if necessary, a dictionary containing query variables to pass to the API. 12 | It returns a :class:`QueryResponse` object, which contains the response data 13 | from the API as well as some metadata about the query. See the documentation 14 | for :class:`QueryHandler` and :class:`QueryResponse` for more details. 15 | 16 | Additionally, the :class:`JSONParser` class is provided for more advanced use 17 | cases. It is not necessary to use this class directly, but it is provided for 18 | those who wish to do so. As of version ``0.5.0``, this class is not being used 19 | internally by any other class, and may be removed in a future version. 20 | 21 | This module currently has no plans to support a CLI interface, and it is 22 | intended to be used as a library for other projects. 23 | 24 | Submodules 25 | ---------- 26 | 27 | .. python-apigen-entity-summary:: splatnet3_scraper.query.QueryHandler 28 | 29 | .. python-apigen-entity-summary:: splatnet3_scraper.query.QueryResponse 30 | 31 | .. python-apigen-entity-summary:: splatnet3_scraper.query.Config 32 | 33 | .. python-apigen-entity-summary:: splatnet3_scraper.query.JSONParser -------------------------------------------------------------------------------- /docs/source/api/scraper/scraper.rst: -------------------------------------------------------------------------------- 1 | Scraper Module 2 | ============== 3 | 4 | The scraper module is the top-level interface provided by this library. It 5 | provides a single class, :class:`SplatNet_Scraper`, which is used to scrape data 6 | from the SplatNet 3 API. This class abstracts away the details of the API and 7 | orchestrates multiple requests to the API to retrieve commonly-used data. This 8 | is the interface best suited for most users, especially those who are not 9 | especially familiar with Python or those who want to get started quickly. 10 | 11 | All query methods of this class return a :class:`QueryResponse` object from the 12 | :mod:`splatnet3_scraper.query` module. This object contains the response data 13 | from the API as well as some metadata about the queries. For more information, 14 | see the documentation for the :mod:`splatnet3_scraper.query` module. 15 | 16 | Submodules 17 | ---------- 18 | 19 | .. python-apigen-entity-summary:: splatnet3_scraper.scraper.SplatNet_Scraper 20 | 21 | .. python-apigen-entity-summary:: splatnet3_scraper.scraper.QueryMap -------------------------------------------------------------------------------- /docs/source/api/utils.rst: -------------------------------------------------------------------------------- 1 | Utils Module 2 | ============ 3 | 4 | This module provides a set of functions that may be used in multiple modules. 5 | The scope of this module is to provide functions that are not specific to any 6 | particular module, to decouple the modules from each other and to avoid code 7 | duplication. 8 | 9 | .. automodule:: splatnet3_scraper.utils 10 | :members: -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | # -- Project information ----------------------------------------------------- 7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 8 | import pathlib 9 | import sys 10 | 11 | sys.path.insert(0, pathlib.Path(__file__).parents[2].resolve().as_posix()) 12 | import splatnet3_scraper 13 | 14 | project = "SplatNet 3 Scraper" 15 | copyright = "2023, Cesar Eduardo Garza" 16 | author = "Cesar Eduardo Garza" 17 | release = splatnet3_scraper.__version__ 18 | 19 | # -- General configuration --------------------------------------------------- 20 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 21 | 22 | 23 | extensions = [ 24 | "sphinx.ext.autodoc", 25 | "sphinx.ext.autosummary", 26 | "sphinx.ext.napoleon", 27 | "sphinx_immaterial", 28 | "sphinx_immaterial.apidoc.python.apigen", 29 | ] 30 | 31 | templates_path = ["_templates"] 32 | exclude_patterns = [] 33 | 34 | python_apigen_modules = { 35 | "splatnet3_scraper": "generated/main/", 36 | "splatnet3_scraper.scraper": "generated/scraper/", 37 | "splatnet3_scraper.query": "generated/query/", 38 | "splatnet3_scraper.auth": "generated/auth/", 39 | } 40 | 41 | python_apigen_default_groups = [ 42 | ("class:.*", "Classes"), 43 | ("data:.*", "Variables"), 44 | ("function:.*", "Functions"), 45 | ("classmethod:.*", "Class methods"), 46 | ("method:.*", "Methods"), 47 | (r"method:.*\.[A-Z][A-Za-z,_]*", "Constructors"), 48 | (r"method:.*\.__[A-Za-z,_]*__", "Special methods"), 49 | (r"method:.*\.__(init|new)__", "Constructors"), 50 | (r"method:.*\.__(str|repr)__", "String representation"), 51 | ("property:.*", "Properties"), 52 | (r".*:.*\.is_[a-z,_]*", "Attributes"), 53 | ] 54 | python_apigen_default_order = [ 55 | ("class:.*", 10), 56 | ("data:.*", 11), 57 | ("function:.*", 12), 58 | ("classmethod:.*", 40), 59 | ("method:.*", 50), 60 | (r"method:.*\.[A-Z][A-Za-z,_]*", 20), 61 | (r"method:.*\.__[A-Za-z,_]*__", 28), 62 | (r"method:.*\.__(init|new)__", 20), 63 | (r"method:.*\.__(str|repr)__", 30), 64 | ("property:.*", 60), 65 | (r".*:.*\.is_[a-z,_]*", 70), 66 | ] 67 | python_apigen_order_tiebreaker = "alphabetical" 68 | python_apigen_case_insensitive_filesystem = False 69 | python_apigen_show_base_classes = True 70 | 71 | napoleon_custom_sections = [("Returns", "params_style")] 72 | 73 | html_theme_options = { 74 | "repo_url": "https://github.com/cesaregarza/SplatNet3_Scraper", 75 | "repo_name": "cesaregarza/SplatNet3_Scraper", 76 | "repo_type": "github", 77 | "social": [ 78 | { 79 | "icon": "fontawesome/brands/github", 80 | "link": "https://github.com/cesaregarza/SplatNet3_Scraper", 81 | } 82 | ], 83 | } 84 | 85 | 86 | # -- Options for HTML output ------------------------------------------------- 87 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 88 | 89 | html_theme = "sphinx_immaterial" 90 | html_static_path = ["_static"] 91 | 92 | # Other options 93 | autodoc_typehints = "description" 94 | 95 | root_doc = "index" 96 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.BASE_TOKENS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.BASE_TOKENS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.add_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.add_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.get.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.get 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.get_all.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.get_all 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.remove_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.remove_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.token_to_variable.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.token_to_variable 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/EnvironmentVariablesManager.variable_to_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.EnvironmentVariablesManager.variable_to_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.get_hashes.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.get_hashes 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.get_query.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.get_query 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.query.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.query 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.query_body.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.query_body 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.query_body_hash.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.query_body_hash 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.query_hash.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.query_hash 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.query_header.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries.query_header 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/GraphQLQueries.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.GraphQLQueries 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.g_token_generation_phase_1.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.g_token_generation_phase_1 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.g_token_generation_phase_2.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.g_token_generation_phase_2 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.generate_login_url.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.generate_login_url 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.generate_new_state.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.generate_new_state 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.generate_new_verifier.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.generate_new_verifier 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_bullet_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_bullet_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_ftoken.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_ftoken 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_gtoken.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_gtoken 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_gtoken_request.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_gtoken_request 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_user_access_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_user_access_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_user_info.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_user_info 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_version.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_version 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.get_web_service_access_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.get_web_service_access_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.new_instance.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.new_instance 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.parse_npf_uri.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.parse_npf_uri 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.set_new_f_token_function.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.set_new_f_token_function 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.splatnet_web_version.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.splatnet_web_version 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.state.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.state 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.verifier.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.verifier 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/NSO.version.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.NSO.version 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.__repr__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.__repr__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.is_expired.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.is_expired 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.is_valid.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.is_valid 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.time_left.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.time_left 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/Token.time_left_str.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.Token.time_left_str 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.add_session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.add_session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.add_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.add_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.data.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.data 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.flag_origin.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.flag_origin 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.from_config_file.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.from_config_file 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.from_env.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.from_env 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.from_session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.from_session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.from_text_file.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.from_text_file 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.generate_all_tokens.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.generate_all_tokens 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.generate_bullet_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.generate_bullet_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.generate_gtoken.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.generate_gtoken 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.get.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.get 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.load.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.load 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.origin.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.origin 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.save.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.save 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.test_tokens.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.test_tokens 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/auth/TokenManager.token_is_valid.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.auth.TokenManager.token_is_valid 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.ACCEPTED_OPTIONS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.ACCEPTED_OPTIONS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.DEFAULT_OPTIONS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.DEFAULT_OPTIONS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.DEPRECATED_OPTIONS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.DEPRECATED_OPTIONS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.add_accepted_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.add_accepted_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.add_default_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.add_default_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.add_deprecated_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.add_deprecated_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.from_env.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.from_env 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.from_s3s_config.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.from_s3s_config 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.generate_token_manager.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.generate_token_manager 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.get.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.get 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.get_data.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.get_data 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.get_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.get_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.initialize_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.initialize_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.manage_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.manage_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.remove_accepted_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.remove_accepted_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.remove_default_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.remove_default_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.remove_deprecated_options.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.remove_deprecated_options 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/Config.save.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.Config.save 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.__eq__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.__eq__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.__repr__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.__repr__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.automatic_type_conversion.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.automatic_type_conversion 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.from_csv.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.from_csv 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.from_gzipped_json.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.from_gzipped_json 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.from_json.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.from_json 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.from_parquet.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.from_parquet 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.remove_columns.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.remove_columns 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.remove_url_columns.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.remove_url_columns 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.to_csv.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.to_csv 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.to_gzipped_json.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.to_gzipped_json 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.to_json.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.to_json 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/JSONParser.to_parquet.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.JSONParser.to_parquet 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.from_config_file.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.from_config_file 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.from_env.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.from_env 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.from_s3s_config.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.from_s3s_config 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.from_session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.from_session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.generate_session_token_url.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.generate_session_token_url 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.query.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.query 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.query_hash.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler.query_hash 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryHandler.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryHandler 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.__eq__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.__eq__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.__getitem__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.__getitem__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.__iter__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.__iter__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.__repr__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.__repr__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.apply.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.apply 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.data.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.data 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.get.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.get 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.items.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.items 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.keys.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.keys 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.match_partial_path.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.match_partial_path 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.metadata.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.metadata 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.parse_json.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.parse_json 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.query.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.query 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.show.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.show 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.timestamp.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.timestamp 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.timestamp_raw.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.timestamp_raw 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/query/QueryResponse.values.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.query.QueryResponse.values 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.ANARCHY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.ANARCHY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.ANARCHY_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.ANARCHY_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.BANKARA_BATTLE_HISTORIES.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.BANKARA_BATTLE_HISTORIES 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.BANKARA_BATTLE_HISTORIES_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.BANKARA_BATTLE_HISTORIES_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.BATTLE_HISTORY_CURRENT_PLAYER.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.BATTLE_HISTORY_CURRENT_PLAYER 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.CATALOG.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.CATALOG 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.CHECKIN.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.CHECKIN 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.CHECKIN_QR.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.CHECKIN_QR 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.CONFIGURE_ANALYTICS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.CONFIGURE_ANALYTICS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_HISTORY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_HISTORY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_HISTORY_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_HISTORY_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_HISTORY_DETAIL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_HISTORY_DETAIL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_PAGER_LATEST_COOP.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_PAGER_LATEST_COOP 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_RECORD.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_RECORD 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_RECORD_BIG_RUN_RECORD_CONTAINER_PAGINATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_RECORD_BIG_RUN_RECORD_CONTAINER_PAGINATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.COOP_RECORD_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.COOP_RECORD_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.CREATE_MY_OUTFIT_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.CREATE_MY_OUTFIT_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_FEST_RECORD_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_FEST_RECORD_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_FEST_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_FEST_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_FEST_VOTING_STATUS_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_FEST_VOTING_STATUS_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_RANKING.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_RANKING 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_AR_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_AR_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_CL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_CL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_GL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_GL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_LF_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_WEAPON_TOPS_LF_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_X_RANKING_AR_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_X_RANKING_AR_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_X_RANKING_CL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_X_RANKING_CL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_X_RANKING_GL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_X_RANKING_GL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_TAB_VIEW_X_RANKING_LF_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_TAB_VIEW_X_RANKING_LF_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DETAIL_VOTING_STATUS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DETAIL_VOTING_STATUS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.DOWNLOAD_SEARCH_REPLAY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.DOWNLOAD_SEARCH_REPLAY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.FEST_RECORD.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.FEST_RECORD 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.FEST_RECORD_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.FEST_RECORD_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.FRIEND_LIST.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.FRIEND_LIST 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.FRIEND_LIST_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.FRIEND_LIST_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.GESOTOWN.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.GESOTOWN 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.GESOTOWN_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.GESOTOWN_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.HERO_HISTORY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.HERO_HISTORY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.HERO_HISTORY_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.HERO_HISTORY_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.HISTORY_RECORD.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.HISTORY_RECORD 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.HISTORY_RECORD_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.HISTORY_RECORD_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.HOME.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.HOME 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.JOURNEY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.JOURNEY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.JOURNEY_CHALLENGE_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.JOURNEY_CHALLENGE_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.JOURNEY_CHALLENGE_DETAIL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.JOURNEY_CHALLENGE_DETAIL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.JOURNEY_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.JOURNEY_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.LATEST.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.LATEST 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.LATEST_BATTLE_HISTORIES.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.LATEST_BATTLE_HISTORIES 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.LATEST_BATTLE_HISTORIES_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.LATEST_BATTLE_HISTORIES_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.LATEST_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.LATEST_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.MY_OUTFITS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.MY_OUTFITS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.MY_OUTFITS_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.MY_OUTFITS_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.MY_OUTFITS_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.MY_OUTFITS_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.MY_OUTFIT_COMMON_DATA_EQUIPMENTS.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.MY_OUTFIT_COMMON_DATA_EQUIPMENTS 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.MY_OUTFIT_COMMON_DATA_FILTERING_CONDITION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.MY_OUTFIT_COMMON_DATA_FILTERING_CONDITION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PAGER_LATEST_VS_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PAGER_LATEST_VS_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PAGER_UPDATE_BATTLE_HISTORIES_BY_VS_MODE.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PAGER_UPDATE_BATTLE_HISTORIES_BY_VS_MODE 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PHOTO_ALBUM.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PHOTO_ALBUM 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PHOTO_ALBUM_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PHOTO_ALBUM_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PRIVATE.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PRIVATE 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PRIVATE_BATTLE_HISTORIES.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PRIVATE_BATTLE_HISTORIES 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PRIVATE_BATTLE_HISTORIES_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PRIVATE_BATTLE_HISTORIES_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.PRIVATE_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.PRIVATE_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.RANKING_HOLDERS_FEST_TEAM_RANKING_HOLDERS_PAGINATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.RANKING_HOLDERS_FEST_TEAM_RANKING_HOLDERS_PAGINATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REFETCHABLE_COOP_HISTORY_COOP_RESULT.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REFETCHABLE_COOP_HISTORY_COOP_RESULT 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REGULAR.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REGULAR 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REGULAR_BATTLE_HISTORIES.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REGULAR_BATTLE_HISTORIES 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REGULAR_BATTLE_HISTORIES_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REGULAR_BATTLE_HISTORIES_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REGULAR_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REGULAR_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REPLAY.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REPLAY 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REPLAY_MODAL_RESERVE_REPLAY_DOWNLOAD_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REPLAY_MODAL_RESERVE_REPLAY_DOWNLOAD_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.REPLAY_UPLOADED_REPLAY_LIST_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.REPLAY_UPLOADED_REPLAY_LIST_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SALE_GEAR_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SALE_GEAR_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SALE_GEAR_DETAIL_ORDER_GESOTOWN_GEAR_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SALE_GEAR_DETAIL_ORDER_GESOTOWN_GEAR_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SALMON.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SALMON 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SALMON_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SALMON_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SALMON_RUN.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SALMON_RUN 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SETTING.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SETTING 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.STAGE_RECORD.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.STAGE_RECORD 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.STAGE_RECORDS_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.STAGE_RECORDS_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.STAGE_SCHEDULE.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.STAGE_SCHEDULE 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.SUPPORT_BUTTON_SUPPORT_CHALLENGE_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.SUPPORT_BUTTON_SUPPORT_CHALLENGE_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.TURF.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.TURF 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.TURF_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.TURF_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.UPDATE_MY_OUTFIT_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.UPDATE_MY_OUTFIT_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.USE_CURRENT_FEST.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.USE_CURRENT_FEST 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.VOTES_UPDATE_FEST_VOTE_MUTATION.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.VOTES_UPDATE_FEST_VOTE_MUTATION 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.VS_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.VS_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.VS_HISTORY_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.VS_HISTORY_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.VS_HISTORY_DETAIL_PAGER_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.VS_HISTORY_DETAIL_PAGER_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.WEAPON_RECORD.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.WEAPON_RECORD 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.WEAPON_RECORDS_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.WEAPON_RECORDS_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.XBATTLE.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.XBATTLE 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.XBATTLE_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.XBATTLE_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_BATTLE_HISTORIES.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_BATTLE_HISTORIES 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_BATTLE_HISTORIES_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_BATTLE_HISTORIES_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_RANKING.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_RANKING 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_RANKING_DETAIL.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_RANKING_DETAIL 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_RANKING_DETAIL_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_RANKING_DETAIL_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.X_RANKING_REFETCH.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.X_RANKING_REFETCH 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.get.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap.get 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/QueryMap.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.QueryMap 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.__init__.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.__init__ 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.from_config_file.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.from_config_file 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.from_env.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.from_env 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.from_s3s_config.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.from_s3s_config 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.from_session_token.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.from_session_token 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.get_vs_battles.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper.get_vs_battles 10 | 11 | -------------------------------------------------------------------------------- /docs/source/generated/scraper/SplatNet_Scraper.rst: -------------------------------------------------------------------------------- 1 | .. 2 | DO NOT EDIT. GENERATED by sphinx_immaterial.apidoc.python.apigen. 3 | 4 | 5 | :hide-edit-link: 6 | 7 | 8 | 9 | .. python-apigen-entity-page:: splatnet3_scraper.scraper.SplatNet_Scraper 10 | 11 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. SplatNet 3 Scraper documentation master file, created by 2 | sphinx-quickstart on Mon Feb 6 22:45:28 2023. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to SplatNet 3 Scraper's documentation! 7 | ============================================== 8 | 9 | **SplatNet 3 Scraper** is a Python library for scraping data from the Splatoon 3 10 | SplatNet 3 API. It is designed to be as lightweight as possible, with minimal 11 | external dependencies to make it easy to use in any project. 12 | 13 | **SplatNet 3 Scraper** started as a fork of `s3s 14 | `_ but has since been rewritten from 15 | scratch while incorporating much of the login flow logic of s3s. As a result, I 16 | am deeply indebted to the authors of s3s for their work. This project would not 17 | have been possible without their efforts. 18 | 19 | See the :doc:`misc/quickstart` page for more information on how to use this library, 20 | including how to :ref:`install ` it. If you are interested in 21 | contributing to this project, see the :doc:`misc/contributing` page. 22 | 23 | 24 | Indices and tables 25 | ================== 26 | 27 | * :ref:`genindex` 28 | * :ref:`modindex` 29 | * :ref:`search` 30 | 31 | Contents 32 | ======== 33 | 34 | .. toctree:: 35 | :maxdepth: 1 36 | 37 | misc/quickstart 38 | misc/session_token 39 | misc/login_flow 40 | misc/queries 41 | misc/contributing 42 | api/scraper/scraper 43 | api/query/query 44 | api/auth/auth 45 | api/utils -------------------------------------------------------------------------------- /docs/source/misc/queries.rst: -------------------------------------------------------------------------------- 1 | Queries 2 | ======= 3 | 4 | This is a list of queries that can be used to get information from the database. 5 | The hashes of the queries are subject to change at random, so the queries listed 6 | below will be referred to by their names. The :doc:`../api/auth/auth` module 7 | contains a class, :class:`GraphQLQueries`, which downloads the latest list of 8 | queries and is highly recommended for use. 9 | 10 | -------------------------------------------------------------------------------- /docs/source/misc/session_token.rst: -------------------------------------------------------------------------------- 1 | Obtaining A Session Token 2 | ========================= 3 | 4 | To use this package, you must first obtain a valid Nintendo session token. This 5 | requires a Nintendo Switch Online membership and does not require having played 6 | at least one online match in Splatoon 3. Neither the ``scraper`` module nor the 7 | ``query`` module currently provide any functionality for obtaining a session 8 | token, but the ``auth`` module provides the functions necessary to do so through 9 | the :class:`NSO` class. The following example shows the first step in obtaining 10 | a session token, which is to obtain a login URL. Details of the login flow can 11 | be found in the :doc:`login_flow` page. 12 | 13 | .. code-block:: python 14 | 15 | from splatnet3_scraper.auth import NSO 16 | 17 | nso = NSO.new_instance() 18 | print(nso.generate_login_url()) 19 | 20 | .. attention:: 21 | It is extremely important that you use the same instance of the ``NSO`` 22 | class throughout the login flow. If you create a new instance, you will 23 | not be able to obtain a session token. This is because the ``NSO`` class 24 | stores variables internally that are required to verify to Nintendo that 25 | you are the same person who requested the login URL. If you create a new 26 | instance, you will be treated as a new person and will be unable to 27 | obtain a session token. 28 | 29 | The above code will print a very long URL to the console. Copy this URL and 30 | paste it into your browser. You will be redirected to a Nintendo login page. 31 | Enter your Nintendo Switch Online credentials and you will be redirected to a 32 | page that looks like this: 33 | 34 | .. image:: ../../assets/login_url.png 35 | :align: center 36 | 37 | Right-click on the red "Select this account" button and select "Copy link 38 | address". You may click the button if you wish, but it will not work as the URL 39 | begins with ``npf``. With the copied URL in hand, you can now obtain a session 40 | token. Use the following code to do so: 41 | 42 | .. code-block:: python 43 | 44 | copied_url = ... 45 | session_token_code = nso.parse_npf_uri(copied_url) 46 | session_token = nso.get_session_token(session_token_code) 47 | 48 | The ``copied_url`` variable should be replaced with the URL you copied from the 49 | browser. The ``session_token_code`` variable will contain the code that is 50 | required to obtain the session token. The ``session_token`` variable will 51 | contain the session token itself, as a string. You can now use this session 52 | token to make requests to the Splatoon 3 API. 53 | 54 | .. warning:: 55 | The session token is valid for two whole years. You functionally will not 56 | need to obtain a new session token unless you lose the one you have, 57 | Nintendo changes the session token format, or the session token expires, in 58 | order of descending likelihood. Make absolutely sure that you do not share 59 | your session token with anyone else. If you do, they will have access to 60 | your Nintendo Switch Online account and will be able to make requests on 61 | your behalf. If you are concerned about your session token being leaked, 62 | you can revoke it. 63 | -------------------------------------------------------------------------------- /examples/.splatnet3_scraper_example: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = TOKEN 3 | gtoken = TOKEN 4 | bullet_token = TOKEN 5 | 6 | [data] 7 | country = US 8 | language = en-US 9 | 10 | [options] 11 | user_agent = USER_AGENT -------------------------------------------------------------------------------- /misc/parse_api_values.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import requests 5 | 6 | 7 | def get_github_file_content(github_url: str) -> dict: 8 | """Gets the content of a file from GitHub. 9 | 10 | Given a URL to a file on GitHub, gets the content of the file and returns 11 | it as a dictionary. Uses the GitHub API to get the content of the file 12 | instead of scraping the GitHub website. 13 | 14 | Args: 15 | github_url (str): The URL to the file on GitHub. 16 | 17 | Returns: 18 | dict: The JSON data from the file. 19 | """ 20 | path_parts = github_url.split("github.com/")[1].split("/") 21 | owner = path_parts[0] 22 | repo = path_parts[1] 23 | # Skips both "blob" and the branch name 24 | path = "/".join(path_parts[4:]) 25 | 26 | api_url = f"https://api.github.com/repos/{owner}/{repo}/contents/{path}" 27 | 28 | headers = {"Accept": "application/vnd.github.v3.raw"} 29 | if "GITHUB_TOKEN" in os.environ: 30 | print("Using GitHub token to get file content") 31 | headers["Authorization"] = f"token {os.environ['GITHUB_TOKEN']}" 32 | else: 33 | print("No GitHub token found, using unauthenticated requests") 34 | 35 | response = requests.get(api_url, headers=headers) 36 | 37 | if response.status_code != 200: 38 | raise ValueError(f"Failed to get file content: {response.status_code}") 39 | return response.json() 40 | 41 | 42 | def parse_splatnet3_app_json( 43 | json_data: dict, 44 | ) -> dict: 45 | return { 46 | "version": json_data["web_app_ver"], 47 | "graphql": {"hash_map": json_data["graphql_queries"]}, 48 | } 49 | 50 | 51 | def parse_tournament_app_json( 52 | json_data: dict, 53 | ) -> dict: 54 | return { 55 | "graphql": {"hash_map": json_data["graphql_queries"]}, 56 | } 57 | 58 | 59 | if __name__ == "__main__": 60 | SPLATNET_URL = ( 61 | "https://github.com/nintendoapis/nintendo-app-versions/" 62 | "blob/main/data/splatnet3-app.json" 63 | ) 64 | TOURNAMENT_URL = ( 65 | "https://github.com/nintendoapis/nintendo-app-versions/" 66 | "blob/main/data/tournament-manager-app.json" 67 | ) 68 | 69 | splatnet3_app_json = get_github_file_content(SPLATNET_URL) 70 | tournament_app_json = get_github_file_content(TOURNAMENT_URL) 71 | parsed_splatnet3_json = parse_splatnet3_app_json(splatnet3_app_json) 72 | parsed_tournament_json = parse_tournament_app_json(tournament_app_json) 73 | 74 | # Write the parsed JSON to files 75 | with open("src/splatnet3_scraper/splatnet3_webview_data.json", "w") as f: 76 | json.dump(parsed_splatnet3_json, f, indent=4) 77 | f.write("\n") 78 | 79 | with open("src/splatnet3_scraper/tournament_webview_data.json", "w") as f: 80 | json.dump(parsed_tournament_json, f, indent=4) 81 | f.write("\n") 82 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "splatnet3_scraper" 3 | version = "1.1.5" 4 | description = "Scraper for SplatNet 3 for Splatoon 3" 5 | authors = ["Cesar E Garza "] 6 | readme = "README.md" 7 | packages = [{include = "splatnet3_scraper", from = "src"}] 8 | license = "GPL-3.0-or-later" 9 | 10 | [tool.poetry.dependencies] 11 | python = "^3.10" 12 | requests = "^2.28.1" 13 | pandas = {version = "^1.5.3", optional = true, extras = ["examples"]} 14 | sqlalchemy = {version = "^2.0.1", optional = true, extras = ["examples"]} 15 | psycopg2 = {version = "^2.9.5", optional = true, extras = ["examples"]} 16 | 17 | [tool.poetry.extras] 18 | parquet = ["pyarrow"] 19 | examples = ["pandas", "sqlalchemy", "psycopg2"] 20 | all = ["parquet", "examples"] 21 | 22 | [tool.poetry.group.dev.dependencies] 23 | black = "^22.12.0" 24 | mypy = "^0.991" 25 | flake8 = "^6.0.0" 26 | darglint = "^1.8.1" 27 | isort = "^5.11.4" 28 | types-requests = "^2.28.11.7" 29 | pytest = "^7.2.0" 30 | coverage = "^7.0.4" 31 | ipykernel = "^6.19.4" 32 | genson = "^1.2.2" 33 | line-profiler = "^4.0.2" 34 | pytest-lazy-fixture = "^0.6.3" 35 | freezegun = "^1.2.2" 36 | pytest-mock = "^3.10.0" 37 | genbadge = {extras = ["all"], version = "^1.1.0"} 38 | pytest-html = "^3.2.0" 39 | sphinx = "^6.1.3" 40 | ipython = "^8.9.0" 41 | 42 | 43 | 44 | [tool.poetry.group.docs.dependencies] 45 | sphinx-immaterial = "^0.11.3" 46 | 47 | [build-system] 48 | requires = ["poetry-core"] 49 | build-backend = "poetry.core.masonry.api" 50 | 51 | 52 | [tool.black] 53 | line-length = 80 54 | target-version = ['py310'] 55 | 56 | [tool.isort] 57 | profile = "black" 58 | line_length = 80 59 | skip_glob = "^(tests|src/splatnet3_scraper)" 60 | 61 | [tool.mypy] 62 | python_version = "3.10" 63 | ignore_missing_imports = true 64 | pretty = true 65 | exclude = [".venv", "tests", "docs", "examples"] 66 | 67 | [tool.pytest.ini_options] 68 | testpaths = "tests" 69 | addopts = [ 70 | "-v", 71 | "--tb=auto", 72 | "--showlocals", 73 | "--color=yes", 74 | "-k not production", 75 | ] 76 | markers = [ 77 | "slow: marks tests as slow (deselect with '-m \"not slow\"')", 78 | "internet: marks tests as requiring internet access (deselect with '-m \"not internet\"')", 79 | "production: marks tests as only running in production (deselect with '-m \"not production\"')", 80 | ] 81 | pythonpath = [ 82 | "src" 83 | ] 84 | -------------------------------------------------------------------------------- /reports/coverage/coverage-badge.svg: -------------------------------------------------------------------------------- 1 | coverage: 97.49%coverage97.49% -------------------------------------------------------------------------------- /reports/flake8/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 61 | 66 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /reports/flake8/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /reports/flake8/flake8-badge.svg: -------------------------------------------------------------------------------- 1 | flake8: 0 C, 0 W, 0 Iflake80 C, 0 W, 0 I -------------------------------------------------------------------------------- /reports/flake8/flake8stats.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/reports/flake8/flake8stats.txt -------------------------------------------------------------------------------- /reports/junit/assets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica, Arial, sans-serif; 3 | font-size: 12px; 4 | /* do not increase min-width as some may use split screens */ 5 | min-width: 800px; 6 | color: #999; 7 | } 8 | 9 | h1 { 10 | font-size: 24px; 11 | color: black; 12 | } 13 | 14 | h2 { 15 | font-size: 16px; 16 | color: black; 17 | } 18 | 19 | p { 20 | color: black; 21 | } 22 | 23 | a { 24 | color: #999; 25 | } 26 | 27 | table { 28 | border-collapse: collapse; 29 | } 30 | 31 | /****************************** 32 | * SUMMARY INFORMATION 33 | ******************************/ 34 | #environment td { 35 | padding: 5px; 36 | border: 1px solid #E6E6E6; 37 | } 38 | #environment tr:nth-child(odd) { 39 | background-color: #f6f6f6; 40 | } 41 | 42 | /****************************** 43 | * TEST RESULT COLORS 44 | ******************************/ 45 | span.passed, 46 | .passed .col-result { 47 | color: green; 48 | } 49 | 50 | span.skipped, 51 | span.xfailed, 52 | span.rerun, 53 | .skipped .col-result, 54 | .xfailed .col-result, 55 | .rerun .col-result { 56 | color: orange; 57 | } 58 | 59 | span.error, 60 | span.failed, 61 | span.xpassed, 62 | .error .col-result, 63 | .failed .col-result, 64 | .xpassed .col-result { 65 | color: red; 66 | } 67 | 68 | /****************************** 69 | * RESULTS TABLE 70 | * 71 | * 1. Table Layout 72 | * 2. Extra 73 | * 3. Sorting items 74 | * 75 | ******************************/ 76 | /*------------------ 77 | * 1. Table Layout 78 | *------------------*/ 79 | #results-table { 80 | border: 1px solid #e6e6e6; 81 | color: #999; 82 | font-size: 12px; 83 | width: 100%; 84 | } 85 | #results-table th, 86 | #results-table td { 87 | padding: 5px; 88 | border: 1px solid #E6E6E6; 89 | text-align: left; 90 | } 91 | #results-table th { 92 | font-weight: bold; 93 | } 94 | 95 | /*------------------ 96 | * 2. Extra 97 | *------------------*/ 98 | .log { 99 | background-color: #e6e6e6; 100 | border: 1px solid #e6e6e6; 101 | color: black; 102 | display: block; 103 | font-family: "Courier New", Courier, monospace; 104 | height: 230px; 105 | overflow-y: scroll; 106 | padding: 5px; 107 | white-space: pre-wrap; 108 | } 109 | .log:only-child { 110 | height: inherit; 111 | } 112 | 113 | div.image { 114 | border: 1px solid #e6e6e6; 115 | float: right; 116 | height: 240px; 117 | margin-left: 5px; 118 | overflow: hidden; 119 | width: 320px; 120 | } 121 | div.image img { 122 | width: 320px; 123 | } 124 | 125 | div.video { 126 | border: 1px solid #e6e6e6; 127 | float: right; 128 | height: 240px; 129 | margin-left: 5px; 130 | overflow: hidden; 131 | width: 320px; 132 | } 133 | div.video video { 134 | overflow: hidden; 135 | width: 320px; 136 | height: 240px; 137 | } 138 | 139 | .collapsed { 140 | display: none; 141 | } 142 | 143 | .expander::after { 144 | content: " (show details)"; 145 | color: #BBB; 146 | font-style: italic; 147 | cursor: pointer; 148 | } 149 | 150 | .collapser::after { 151 | content: " (hide details)"; 152 | color: #BBB; 153 | font-style: italic; 154 | cursor: pointer; 155 | } 156 | 157 | /*------------------ 158 | * 3. Sorting items 159 | *------------------*/ 160 | .sortable { 161 | cursor: pointer; 162 | } 163 | 164 | .sort-icon { 165 | font-size: 0px; 166 | float: left; 167 | margin-right: 5px; 168 | margin-top: 5px; 169 | /*triangle*/ 170 | width: 0; 171 | height: 0; 172 | border-left: 8px solid transparent; 173 | border-right: 8px solid transparent; 174 | } 175 | .inactive .sort-icon { 176 | /*finish triangle*/ 177 | border-top: 8px solid #E6E6E6; 178 | } 179 | .asc.active .sort-icon { 180 | /*finish triangle*/ 181 | border-bottom: 8px solid #999; 182 | } 183 | .desc.active .sort-icon { 184 | /*finish triangle*/ 185 | border-top: 8px solid #999; 186 | } 187 | -------------------------------------------------------------------------------- /reports/junit/test-badge.svg: -------------------------------------------------------------------------------- 1 | tests: 535tests535 -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=cesaregarza_SplatNet3_Scraper 2 | sonar.organization=cesaregarza 3 | 4 | sonar.python.coverage.reportPaths=./coverage.xml 5 | sonar.python.version=3.10 6 | 7 | # This is the name and version displayed in the SonarCloud UI. 8 | #sonar.projectName=SplatNet3_Scraper 9 | #sonar.projectVersion=1.0 10 | 11 | 12 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 13 | #sonar.sources=. 14 | 15 | # Encoding of the source code. Default is default system encoding 16 | #sonar.sourceEncoding=UTF-8 -------------------------------------------------------------------------------- /src/splatnet3_scraper/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib.metadata 2 | 3 | try: 4 | __version__ = importlib.metadata.version(__name__) 5 | except importlib.metadata.PackageNotFoundError: 6 | # Backup version number 7 | __version__ = "0.10.2" 8 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.auth.graph_ql_queries import GraphQLQueries 2 | from splatnet3_scraper.auth.nso import NSO 3 | from splatnet3_scraper.auth.tokens import ( 4 | EnvironmentVariablesManager, 5 | Token, 6 | TokenKeychain, 7 | TokenManager, 8 | TokenManagerConstructor, 9 | TokenRegenerator, 10 | ) 11 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/exceptions.py: -------------------------------------------------------------------------------- 1 | class NintendoException(Exception): 2 | """Base class for all Nintendo exceptions.""" 3 | 4 | pass 5 | 6 | 7 | class FTokenException(Exception): 8 | """Base class for all Imink exceptions.""" 9 | 10 | pass 11 | 12 | 13 | class SplatNetException(Exception): 14 | """Base class for all Splatnet exceptions.""" 15 | 16 | pass 17 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/tokens/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.auth.tokens.constructor import TokenManagerConstructor 2 | from splatnet3_scraper.auth.tokens.environment_manager import ( 3 | EnvironmentVariablesManager, 4 | ) 5 | from splatnet3_scraper.auth.tokens.keychain import TokenKeychain 6 | from splatnet3_scraper.auth.tokens.manager import TokenManager 7 | from splatnet3_scraper.auth.tokens.regenerator import TokenRegenerator 8 | from splatnet3_scraper.auth.tokens.tokens import Token 9 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/tokens/environment_manager.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from splatnet3_scraper.constants import ENV_VAR_NAMES, TOKENS 4 | 5 | 6 | class EnvironmentVariablesManager: 7 | """Manages environment variables for the scraper. 8 | 9 | This class is used to manage the environment variables in an easy way. Any 10 | environment variable calls should be done through this class, it will handle 11 | obtaining the environment variables, allow additional environment variables 12 | to be added and defined, and will also handle the base environment variables 13 | that are required for this package to work. 14 | """ 15 | 16 | BASE_TOKENS = [TOKENS.SESSION_TOKEN, TOKENS.GTOKEN, TOKENS.BULLET_TOKEN] 17 | 18 | def __init__(self) -> None: 19 | """Initializes the class and sets up the base environment variables.""" 20 | self.variable_names = {} 21 | for token in self.BASE_TOKENS: 22 | self.variable_names[token] = ENV_VAR_NAMES[token] 23 | 24 | def token_to_variable(self, token: str) -> str: 25 | """Given the token name, returns the environment variable name. 26 | 27 | Args: 28 | token (str): The token name. 29 | 30 | Returns: 31 | str: The environment variable name. 32 | """ 33 | return self.variable_names[token] 34 | 35 | def variable_to_token(self, variable: str) -> str: 36 | """Given the environment variable name, returns the token name. 37 | 38 | Args: 39 | variable (str): The environment variable name. 40 | 41 | Raises: 42 | KeyError: If the variable is not defined. 43 | 44 | Returns: 45 | str: The token name. 46 | """ 47 | for token, variable_name in self.variable_names.items(): 48 | if variable_name == variable: 49 | return token 50 | raise KeyError(f"Variable {variable} is not defined.") 51 | 52 | def add_token(self, token_name: str, variable_name: str) -> None: 53 | """Adds a new token to the environment variables. 54 | 55 | Args: 56 | token_name (str): The token name. 57 | variable_name (str): The environment variable name. 58 | """ 59 | self.variable_names[token_name] = variable_name 60 | 61 | def remove_token(self, token_name: str) -> None: 62 | """Removes a token from the environment variables. 63 | 64 | Args: 65 | token_name (str): The token name. 66 | 67 | Raises: 68 | ValueError: If the token is a base token. 69 | """ 70 | if token_name in self.BASE_TOKENS: 71 | raise ValueError(f"Cannot remove base token {token_name}.") 72 | del self.variable_names[token_name] 73 | 74 | def get(self, token: str) -> str | None: 75 | """Gets the environment variable for the given token. 76 | 77 | Args: 78 | token (str): The token to get the environment variable for. 79 | 80 | Returns: 81 | str | None: The environment variable, or None if it is not set. 82 | """ 83 | return os.environ.get(self.token_to_variable(token)) 84 | 85 | def get_all(self) -> dict[str, str | None]: 86 | """Gets all the environment variables. 87 | 88 | Returns: 89 | dict[str, str]: The environment variables. 90 | """ 91 | return {token: self.get(token) for token in self.variable_names.keys()} 92 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/tokens/token_typing.py: -------------------------------------------------------------------------------- 1 | from typing import Literal, TypeAlias 2 | 3 | ORIGIN: TypeAlias = Literal[ 4 | "memory", 5 | "env", 6 | "file", 7 | ] 8 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/auth/tokens/tokens.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from splatnet3_scraper.constants import TOKEN_EXPIRATIONS 4 | 5 | 6 | class Token: 7 | """Class that represents a token. This class is meant to store the token 8 | itself, the type of token it is, and the time it was created. It can be used 9 | to check if the token is expired or display the time left before it expires. 10 | It also provides convenience methods for getting all sorts of metadata about 11 | the token. 12 | """ 13 | 14 | def __init__(self, value: str, name: str, timestamp: float) -> None: 15 | """Initializes a ``Token`` object. The expiration time is calculated 16 | based on the token type, with a default of ``1e10`` seconds (about 316 17 | days, this should be basically forever for all intents and purposes; if 18 | you have a python session running for that long, you have bigger 19 | problems than a token expiring). 20 | 21 | Args: 22 | value (str): The value of the token, this is the actual token. 23 | name (str): The name of the token, this is used to identify which 24 | type of token it represents, making it easier for the manager 25 | to handle the tokens when searching for a specific one. It also 26 | determines the expiration time of the token. 27 | timestamp (float): The time the token was created, in seconds since 28 | the epoch. This is used to determine if the token is expired. 29 | """ 30 | self.value = value 31 | self.name = name 32 | self.timestamp = timestamp 33 | self.expiration = TOKEN_EXPIRATIONS.get(name, 1e10) + timestamp 34 | 35 | @property 36 | def is_valid(self) -> bool: 37 | """A very rudimentary check to see if the token is valid. This is not 38 | a guarantee that the token is valid, but it is a good indicator that 39 | it is for most cases. It checks if the token is not None and if it is 40 | not an empty string. This usually means that the token is valid, but 41 | it is not a guarantee. This is also here in case a future version of 42 | the API requires a different check to determine if a token is valid. 43 | 44 | Returns: 45 | bool: True if the token is valid (not None and not an empty string) 46 | False otherwise. 47 | """ 48 | return (self.value is not None) and (self.value != "") 49 | 50 | @property 51 | def is_expired(self) -> bool: 52 | """Checks if the token is expired. This is done by comparing the 53 | current time to the expiration time of the token. If the current time 54 | is greater than the expiration time, the token is expired. This is not 55 | a guarantee that the token is expired, but it is a good indicator that 56 | it is for most cases. 57 | 58 | Returns: 59 | bool: True if the token is expired, False otherwise. 60 | """ 61 | return self.time_left <= 0 62 | 63 | @property 64 | def time_left(self) -> float: 65 | """Returns the time left before the token expires. If the token is 66 | expired, a negative number will be returned. This is not a guarantee 67 | that the token is expired, but it is a good indicator that it is for 68 | most cases. 69 | 70 | Returns: 71 | float: The time left before the token expires. 72 | """ 73 | return self.expiration - time.time() 74 | 75 | @property 76 | def time_left_str(self) -> str: 77 | """A string representation of the time left before the token expires. 78 | If the token is expired, "Expired" will be returned. This is not a 79 | guarantee that the token is expired, but it is a good indicator that 80 | it is for most cases. If the time left is greater than 100,000 hours, 81 | "basically forever" will be returned. If you have a python session 82 | running for that long, you have bigger problems than a token expiring. 83 | 84 | Returns: 85 | str: A string representation of the time left before the token 86 | expires. 87 | """ 88 | time_left = self.time_left 89 | if time_left <= 0: 90 | return "Expired" 91 | mins, secs = divmod(time_left, 60) 92 | hours, mins = divmod(mins, 60) 93 | 94 | out = "" 95 | if hours > 1e5: 96 | return "basically forever" 97 | if hours > 0: 98 | out += f"{hours:.0f}h " 99 | if mins > 0: 100 | out += f"{mins:.0f}m " 101 | if secs > 0: 102 | out += f"{secs:.1f}s" 103 | return out.strip() 104 | 105 | def __repr__(self) -> str: 106 | out = "Token(" 107 | spaces = " " * len(out) 108 | out += ( 109 | f"value={self.value[:5]}...,\n" 110 | + spaces 111 | + f"name={self.name},\n" 112 | + spaces 113 | + "expires in " 114 | + self.time_left_str 115 | + "\n)" 116 | ) 117 | return out 118 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/constants.py: -------------------------------------------------------------------------------- 1 | SPLATNET_URL = "https://api.lp1.av5ja.srv.nintendo.net" 2 | GRAPHQL_URL = SPLATNET_URL + "/api/graphql" 3 | GRAPH_QL_REFERENCE_URL = ( 4 | "https://raw.githubusercontent.com" 5 | "/imink-app/SplatNet3/master/Data/splatnet3_webview_data.json" 6 | ) 7 | IOS_APP_URL = ( 8 | "https://apps.apple.com/us/app/nintendo-switch-online/id1234806557" 9 | ) 10 | IMINK_URL = "https://api.imink.app/f" 11 | NXAPI_ZNCA_URL = "https://nxapi-znca-api.fancy.org.uk/api/znca/f" 12 | DEFAULT_F_TOKEN_URL = [NXAPI_ZNCA_URL, IMINK_URL] 13 | DEFAULT_USER_AGENT = ( 14 | "Mozilla/5.0 (Linux; Android 14; Pixel 7a) " 15 | + "AppleWebKit/537.36 (KHTML, like Gecko) " 16 | + "Chrome/120.0.6099.230 " 17 | + "Mobile Safari/537.36" 18 | ) 19 | APP_VERSION_FALLBACK = "2.10.1" 20 | 21 | 22 | class TOKENS: 23 | SESSION_TOKEN = "session_token" 24 | GTOKEN = "gtoken" 25 | BULLET_TOKEN = "bullet_token" 26 | 27 | 28 | TOKEN_EXPIRATIONS = { 29 | TOKENS.GTOKEN: (60 * 60 * 6) + (60 * 30), 30 | TOKENS.BULLET_TOKEN: (60 * 60 * 2), 31 | } 32 | ENV_VAR_NAMES = { 33 | TOKENS.SESSION_TOKEN: "SN3S_SESSION_TOKEN", 34 | TOKENS.GTOKEN: "SN3S_GTOKEN", 35 | TOKENS.BULLET_TOKEN: "SN3S_BULLET_TOKEN", 36 | } 37 | 38 | PRIMARY_ONLY = [ 39 | "Comeback", 40 | "Last-Ditch Effort", 41 | "Opening Gambit", 42 | "Tenacity", 43 | "Ability Doubler", 44 | "Haunt", 45 | "Ninja Squid", 46 | "Respawn Punisher", 47 | "Thermal Ink", 48 | "Drop Roller", 49 | "Object Shredder", 50 | "Stealth Jump", 51 | ] 52 | 53 | ABILITIES = [ 54 | "Ink Saver (Main)", 55 | "Ink Saver (Sub)", 56 | "Ink Recovery Up", 57 | "Run Speed Up", 58 | "Swim Speed Up", 59 | "Special Charge Up", 60 | "Special Saver", 61 | "Special Power Up", 62 | "Quick Respawn", 63 | "Quick Super Jump", 64 | "Sub Power Up", 65 | "Ink Resistance Up", 66 | "Sub Resistance Up", 67 | "Intensify Action", 68 | ] 69 | 70 | ALL_ABILITIES = PRIMARY_ONLY + ABILITIES 71 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/query/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.query.config import Config 2 | from splatnet3_scraper.query.handler import QueryHandler 3 | from splatnet3_scraper.query.json_parser import JSONParser 4 | from splatnet3_scraper.query.responses import QueryResponse 5 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/query/config/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.query.config.config import Config 2 | from splatnet3_scraper.query.config.config_option import ConfigOption 3 | from splatnet3_scraper.query.config.config_option_handler import ( 4 | ConfigOptionHandler, 5 | ) 6 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/query/config/callbacks.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | delimiter = re.compile(r"\s*\,\s*") 4 | 5 | 6 | # Make sure all callbacks return values, even if they are not transformed. 7 | def session_token_callback( 8 | session_token: str | None, 9 | ) -> str: 10 | if session_token is None: 11 | raise ValueError("Session token must be provided.") 12 | return session_token 13 | 14 | 15 | def f_token_url_callback(f_token_url: str | list[str] | None) -> list[str]: 16 | if f_token_url is None: 17 | raise ValueError("F token URL must be provided.") 18 | elif isinstance(f_token_url, list): 19 | return f_token_url 20 | else: 21 | return delimiter.split(f_token_url) 22 | 23 | 24 | def f_token_url_save_callback(f_token_url: list[str] | None) -> str: 25 | if f_token_url is None: 26 | raise ValueError("F token URL must be provided.") 27 | return ",".join(f_token_url) 28 | 29 | 30 | def log_level_callback(log_level: str | None) -> str: 31 | # Does not set the log level, just checks that it is valid 32 | if log_level is None: 33 | return "INFO" 34 | try: 35 | log_level = log_level.upper() 36 | assert log_level in ("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG") 37 | return log_level 38 | except AssertionError: 39 | raise ValueError( 40 | "Log level must be one of CRITICAL, ERROR, WARNING, INFO, DEBUG" 41 | ) from None 42 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/scraper/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.scraper.main import SplatNet_Scraper 2 | from splatnet3_scraper.scraper.query_map import QueryMap 3 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from splatnet3_scraper.utils.hash_data import ( 2 | fallback_path, 3 | get_fallback_hash_data, 4 | get_hash_data, 5 | get_splatnet_hashes, 6 | get_splatnet_version, 7 | get_ttl_hash, 8 | ) 9 | from splatnet3_scraper.utils.json_helpers import ( 10 | delinearize_json, 11 | enumerate_all_paths, 12 | linearize_json, 13 | match_partial_path, 14 | ) 15 | from splatnet3_scraper.utils.retry import retry 16 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/utils/hash_data.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | import pathlib 4 | import time 5 | from functools import lru_cache 6 | 7 | import requests 8 | 9 | from splatnet3_scraper.constants import GRAPH_QL_REFERENCE_URL 10 | 11 | fallback_path = ( 12 | pathlib.Path(__file__).parent.parent / "splatnet3_webview_data.json" 13 | ) 14 | 15 | 16 | @lru_cache() 17 | def get_hash_data( 18 | url: str | None = None, ttl_hash: int | None = None 19 | ) -> tuple[dict, str]: 20 | """Gets the hash data for the GraphQL queries with a time-to-live (TTL) 21 | cache. 22 | 23 | Uses requests to get the `imink` GraphQL query hash map JSON file and 24 | parses it to get the hashes for the queries. The initial request 25 | response contains two keys: ``hash_map`` and ``version``. Both of these 26 | are returned as a tuple, with the first element being the ``hash_map`` 27 | and the second element being the ``version``. 28 | 29 | Args: 30 | url (str | None): The URL to get the hash data from. If None, the 31 | default URL will be used, from `imink`. This can be found in the 32 | ``GRAPH_QL_REFERENCE_URL`` variable. Defaults to None. 33 | ttl_hash (int | None): The hash to use for the TTL cache. This is used 34 | to determine if the cache should be used or not. The hash is 35 | calculated by dividing the current time by the expiry time in 36 | seconds and rounding to the nearest integer. If None, the default 37 | expiry time of 15 minutes will be used. Note that this method of TTL 38 | caching does not guarantee that the cache will be invalidated after 39 | the expiry time, but it is a good enough approximation. Defaults to 40 | None. 41 | 42 | Returns: 43 | dict[str, str]: The hash map for the GraphQL queries. 44 | str: The version of the hash map. 45 | """ 46 | del ttl_hash 47 | 48 | request_url = url or GRAPH_QL_REFERENCE_URL 49 | response = requests.get(request_url).json() 50 | return response["graphql"]["hash_map"], response["version"] 51 | 52 | 53 | def get_ttl_hash(expiry_time_seconds: float = 15 * 60) -> int: 54 | return round(time.time() / expiry_time_seconds) 55 | 56 | 57 | @lru_cache() 58 | def get_fallback_hash_data() -> tuple[dict, str]: 59 | """Gets the fallback hash data for the GraphQL queries. 60 | 61 | Loads the fallback hash data from the ``splatnet3_webview_data.json`` file 62 | and parses it to get the hashes for the queries. 63 | 64 | Returns: 65 | tuple[dict, str]: 66 | dict: The hash map for the GraphQL queries. 67 | str: The version of the hash map. 68 | """ 69 | with open(fallback_path, "r") as f: 70 | FALLBACK_DATA = json.load(f) 71 | 72 | return FALLBACK_DATA["graphql"]["hash_map"], FALLBACK_DATA["version"] 73 | 74 | 75 | def get_splatnet_hashes(url: str | None = None) -> dict[str, str]: 76 | """Gets the hashes for the GraphQL queries. 77 | 78 | Uses requests to get the `imink` GraphQL query hash map JSON file and 79 | parses it to get the hashes for the queries. The initial request 80 | response contains two keys: ``hash_map`` and ``version``. The 81 | ``hash_map`` key is the dictionary that contains the hashes for the 82 | queries and is what is returned by this method. The `version` key is the 83 | version of the hashes and is used to check if the hashes are up to date, 84 | it is used elsewhere in this package, but is not used here. 85 | 86 | Args: 87 | url (str | None): The URL to get the hash data from. If None, the 88 | default URL will be used, from `imink`. This can be found in the 89 | ``GRAPH_QL_REFERENCE_URL`` constant. 90 | 91 | Returns: 92 | dict[str, str]: The hashes for the GraphQL queries. The keys are 93 | the names of the queries and the values are the most up to date 94 | hashes for the queries. 95 | 96 | # noqa: DAR401 ValueError 97 | """ 98 | try: 99 | hash_data, _ = get_hash_data(url, get_ttl_hash()) 100 | # If the hash data is empty, use the fallback 101 | if not hash_data: 102 | raise ValueError("Hash data is empty") 103 | except Exception as e: 104 | logging.warning(f"Failed to get hash data: {e}") 105 | logging.warning("Using fallback") 106 | return get_fallback_hash_data()[0] 107 | return hash_data 108 | 109 | 110 | def get_splatnet_version(url: str | None = None) -> str: 111 | """Gets the version of the GraphQL queries. 112 | 113 | Uses requests to get the `imink` GraphQL query hash map JSON file and 114 | parses it to get the version of the queries. The initial request 115 | response contains two keys: ``hash_map`` and ``version``. The 116 | ``version`` key is the version of the hashes and is what is returned by 117 | this method. The `hash_map` key is the dictionary that contains the 118 | hashes for the queries and is used elsewhere in this package, but is not 119 | used here. 120 | 121 | Args: 122 | url (str | None): The URL to get the hash data from. If None, the 123 | default URL will be used, from `imink`. This can be found in the 124 | ``GRAPH_QL_REFERENCE_URL`` constant. 125 | 126 | Returns: 127 | str: The version of the GraphQL queries. 128 | 129 | # noqa: DAR401 ValueError 130 | """ 131 | try: 132 | hash_data, version = get_hash_data(url, get_ttl_hash()) 133 | # If the hash data is empty, use the fallback 134 | if not hash_data: 135 | raise ValueError("Hash data is empty") 136 | except Exception as e: 137 | logging.warning(f"Failed to get hash data: {e}") 138 | logging.warning("Using fallback") 139 | return get_fallback_hash_data()[1] 140 | return version 141 | -------------------------------------------------------------------------------- /src/splatnet3_scraper/utils/retry.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from functools import wraps 3 | from typing import Callable, Literal, ParamSpec, Type, TypeAlias, TypeVar 4 | 5 | T = TypeVar("T") 6 | P = ParamSpec("P") 7 | 8 | Backoff: TypeAlias = Literal["fixed", "exponential", "fibonacci"] 9 | 10 | 11 | def retry( 12 | times: int, 13 | exceptions: tuple[Type[Exception], ...] | Type[Exception] = Exception, 14 | call_on_fail: Callable[[], None] | None = None, 15 | ) -> Callable[[Callable[P, T]], Callable[P, T]]: 16 | """Decorator that retries a function a specified number of times if it 17 | raises a specific exception or tuple of exceptions. 18 | 19 | Args: 20 | times (int): Max number of times to retry the function before raising 21 | the exception. 22 | exceptions (tuple[Type[Exception], ...] | Type[Exception]): Exception 23 | or tuple of exceptions to catch. Defaults to Exception. 24 | call_on_fail (Callable[[], None] | None): Function to call if the 25 | function fails. If None, nothing will be called. Defaults to None. 26 | 27 | Returns: 28 | Callable[[Callable[P, T]], Callable[P, T]]: The decorated function, 29 | which will retry the function if it raises an exception. 30 | """ 31 | 32 | def decorator(func: Callable[P, T]) -> Callable[P, T]: 33 | @wraps(func) 34 | def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: 35 | for i in range(times): 36 | try: 37 | return func(*args, **kwargs) 38 | except exceptions: 39 | logging.warning( 40 | "%s failed on attempt %d of %d, retrying.", 41 | func.__name__, 42 | i + 1, 43 | times + 1, 44 | ) 45 | if call_on_fail is not None: 46 | logging.debug("Calling %s...", call_on_fail.__name__) 47 | call_on_fail() 48 | 49 | return func(*args, **kwargs) 50 | 51 | return wrapper 52 | 53 | return decorator 54 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/__init__.py -------------------------------------------------------------------------------- /tests/auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/auth/__init__.py -------------------------------------------------------------------------------- /tests/auth/test_environment_manager.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from splatnet3_scraper.auth.tokens.environment_manager import ( 4 | EnvironmentVariablesManager, 5 | ) 6 | from splatnet3_scraper.constants import ENV_VAR_NAMES, TOKENS 7 | 8 | 9 | class TestEnvironmentVariablesManager: 10 | def test_init(self): 11 | manager = EnvironmentVariablesManager() 12 | assert manager.variable_names == { 13 | TOKENS.SESSION_TOKEN: ENV_VAR_NAMES[TOKENS.SESSION_TOKEN], 14 | TOKENS.GTOKEN: ENV_VAR_NAMES[TOKENS.GTOKEN], 15 | TOKENS.BULLET_TOKEN: ENV_VAR_NAMES[TOKENS.BULLET_TOKEN], 16 | } 17 | 18 | def test_token_to_variable(self): 19 | manager = EnvironmentVariablesManager() 20 | assert ( 21 | manager.token_to_variable(TOKENS.SESSION_TOKEN) 22 | == ENV_VAR_NAMES[TOKENS.SESSION_TOKEN] 23 | ) 24 | assert ( 25 | manager.token_to_variable(TOKENS.GTOKEN) 26 | == ENV_VAR_NAMES[TOKENS.GTOKEN] 27 | ) 28 | assert ( 29 | manager.token_to_variable(TOKENS.BULLET_TOKEN) 30 | == ENV_VAR_NAMES[TOKENS.BULLET_TOKEN] 31 | ) 32 | 33 | def test_variable_to_token(self): 34 | manager = EnvironmentVariablesManager() 35 | assert ( 36 | manager.variable_to_token(ENV_VAR_NAMES[TOKENS.SESSION_TOKEN]) 37 | == TOKENS.SESSION_TOKEN 38 | ) 39 | assert ( 40 | manager.variable_to_token(ENV_VAR_NAMES[TOKENS.GTOKEN]) 41 | == TOKENS.GTOKEN 42 | ) 43 | assert ( 44 | manager.variable_to_token(ENV_VAR_NAMES[TOKENS.BULLET_TOKEN]) 45 | == TOKENS.BULLET_TOKEN 46 | ) 47 | with pytest.raises(KeyError): 48 | manager.variable_to_token("test_variable") 49 | 50 | def test_add_token(self): 51 | manager = EnvironmentVariablesManager() 52 | assert "test_token" not in manager.variable_names 53 | manager.add_token("test_token", "test_variable") 54 | assert manager.variable_names["test_token"] == "test_variable" 55 | 56 | def test_remove_token(self): 57 | manager = EnvironmentVariablesManager() 58 | assert TOKENS.SESSION_TOKEN in manager.variable_names 59 | for token in manager.BASE_TOKENS: 60 | with pytest.raises(ValueError): 61 | manager.remove_token(token) 62 | 63 | manager.add_token("test_token", "test_variable") 64 | assert "test_token" in manager.variable_names 65 | manager.remove_token("test_token") 66 | assert "test_token" not in manager.variable_names 67 | 68 | def test_get(self, monkeypatch: pytest.MonkeyPatch): 69 | manager = EnvironmentVariablesManager() 70 | with monkeypatch.context() as ctx: 71 | test_token = "test_session_token" 72 | ctx.setenv(ENV_VAR_NAMES[TOKENS.SESSION_TOKEN], test_token) 73 | assert manager.get(TOKENS.SESSION_TOKEN) == test_token 74 | assert manager.get(TOKENS.GTOKEN) is None 75 | 76 | @pytest.mark.parametrize( 77 | "session_token", 78 | [None, "test_session_token"], 79 | ids=["no_session_token", "session_token"], 80 | ) 81 | @pytest.mark.parametrize( 82 | "gtoken", 83 | [None, "test_gtoken"], 84 | ids=["no_gtoken", "gtoken"], 85 | ) 86 | @pytest.mark.parametrize( 87 | "bullet_token", 88 | [None, "test_bullet_token"], 89 | ids=["no_bullet_token", "bullet_token"], 90 | ) 91 | @pytest.mark.parametrize( 92 | "extra_token", 93 | [None, "test_extra_token"], 94 | ids=["no_extra_token", "extra_token"], 95 | ) 96 | def test_get_all( 97 | self, 98 | session_token: str, 99 | gtoken: str, 100 | bullet_token: str, 101 | extra_token: str, 102 | monkeypatch: pytest.MonkeyPatch, 103 | ): 104 | manager = EnvironmentVariablesManager() 105 | if extra_token is not None: 106 | manager.add_token("test_token", "test_variable") 107 | 108 | with monkeypatch.context() as ctx: 109 | if session_token is not None: 110 | ctx.setenv(ENV_VAR_NAMES[TOKENS.SESSION_TOKEN], session_token) 111 | if gtoken is not None: 112 | ctx.setenv(ENV_VAR_NAMES[TOKENS.GTOKEN], gtoken) 113 | if bullet_token is not None: 114 | ctx.setenv(ENV_VAR_NAMES[TOKENS.BULLET_TOKEN], bullet_token) 115 | if extra_token is not None: 116 | ctx.setenv("test_variable", extra_token) 117 | 118 | tokens = manager.get_all() 119 | assert isinstance(tokens, dict) 120 | assert tokens[TOKENS.SESSION_TOKEN] == session_token 121 | assert tokens[TOKENS.GTOKEN] == gtoken 122 | assert tokens[TOKENS.BULLET_TOKEN] == bullet_token 123 | if extra_token is not None: 124 | assert tokens["test_token"] == extra_token 125 | -------------------------------------------------------------------------------- /tests/auth/tokens/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/auth/tokens/__init__.py -------------------------------------------------------------------------------- /tests/auth/tokens/test_keychain.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import freezegun 4 | import pytest 5 | 6 | from splatnet3_scraper.auth.tokens.keychain import TokenKeychain 7 | from splatnet3_scraper.auth.tokens.tokens import Token 8 | 9 | test_date_str = "2023-01-01 00:00:00" 10 | with freezegun.freeze_time(test_date_str): 11 | test_date_float = time.time() 12 | 13 | 14 | class TestTokenKeychain: 15 | 16 | token = Token("test_value", "test_name", test_date_float) 17 | 18 | def test_init(self) -> None: 19 | keychain = TokenKeychain() 20 | assert keychain.keychain == {} 21 | 22 | def test_from_dict(self) -> None: 23 | keychain = TokenKeychain.from_dict({self.token.name: self.token}) 24 | assert keychain.keychain == {self.token.name: self.token} 25 | 26 | def test_from_list(self) -> None: 27 | keychain = TokenKeychain.from_list([self.token]) 28 | assert keychain.keychain == {self.token.name: self.token} 29 | 30 | def test_to_dict(self) -> None: 31 | keychain = TokenKeychain.from_list([self.token]) 32 | assert keychain.to_dict() == {self.token.name: self.token.value} 33 | 34 | def test_get(self) -> None: 35 | keychain = TokenKeychain.from_list([self.token]) 36 | assert keychain.get(self.token.name) == self.token.value 37 | with pytest.raises(ValueError): 38 | keychain.get("invalid") 39 | 40 | assert keychain.get(self.token.name, full_token=True) == self.token 41 | 42 | def test_generate_token(self) -> None: 43 | keychain = TokenKeychain() 44 | with freezegun.freeze_time(test_date_str) as frozen_time: 45 | frozen_time.tick(60) 46 | new_token = keychain.generate_token( 47 | self.token.name, self.token.value 48 | ) 49 | assert new_token.value == self.token.value 50 | assert new_token.name == self.token.name 51 | assert new_token.timestamp == test_date_float + 60 52 | 53 | @pytest.mark.parametrize( 54 | "value", 55 | [Token("test_value", "test_name", test_date_float), "test_value"], 56 | ids=["full_token", "from_values"], 57 | ) 58 | @pytest.mark.parametrize( 59 | "token_name", 60 | ["test_name", None], 61 | ids=["token_name", "no_token_name"], 62 | ) 63 | @pytest.mark.parametrize( 64 | "timestamp", 65 | [test_date_float, None], 66 | ids=["timestamp", "no_timestamp"], 67 | ) 68 | def test_add_token( 69 | self, 70 | value: str | Token, 71 | token_name: str | None, 72 | timestamp: float | None, 73 | ) -> None: 74 | keychain = TokenKeychain() 75 | if isinstance(value, str) and token_name is None: 76 | with pytest.raises(ValueError): 77 | keychain.add_token(value, token_name, timestamp) 78 | return 79 | 80 | with freezegun.freeze_time(test_date_str) as frozen_time: 81 | new_token = keychain.add_token(value, token_name, timestamp) 82 | assert new_token.value == self.token.value 83 | assert new_token.name == self.token.name 84 | if timestamp is None: 85 | assert new_token.timestamp == test_date_float 86 | else: 87 | assert new_token.timestamp == timestamp 88 | assert keychain.get(self.token.name) == self.token.value 89 | frozen_time.tick(60) 90 | new_timestamp = time.time() 91 | overwrite_token = keychain.add_token( 92 | "overwrite_value", self.token.name, new_timestamp 93 | ) 94 | assert keychain.get(self.token.name) == "overwrite_value" 95 | assert overwrite_token.timestamp == new_timestamp 96 | assert overwrite_token != new_token 97 | -------------------------------------------------------------------------------- /tests/auth/tokens/test_tokens.py: -------------------------------------------------------------------------------- 1 | import math 2 | import time 3 | 4 | import freezegun 5 | 6 | from splatnet3_scraper.auth.tokens.tokens import Token 7 | 8 | test_date_str = "2023-01-01 00:00:00" 9 | 10 | 11 | def mock_token(token_name: str) -> Token: 12 | with freezegun.freeze_time(test_date_str): 13 | return Token(token_name, token_name, time.time()) 14 | 15 | 16 | class TestToken: 17 | @freezegun.freeze_time("2023-01-01 00:00:00") 18 | def test_new_token(self): 19 | timestamp = time.time() 20 | token = Token("test", "test_name", timestamp) 21 | assert token.value == "test" 22 | assert token.name == "test_name" 23 | assert token.timestamp == timestamp 24 | assert math.isclose(token.expiration, timestamp + 1e10) 25 | 26 | @freezegun.freeze_time("2023-01-01 00:00:00") 27 | def test_properties(self): 28 | token = mock_token("test") 29 | assert token.is_expired is False 30 | assert token.is_valid is True 31 | assert math.isclose(token.time_left, 1e10) 32 | assert token.time_left_str == "basically forever" 33 | 34 | token = mock_token("gtoken") 35 | assert token.time_left_str == "6h 30m" 36 | with freezegun.freeze_time("2023-01-01 06:00:00") as frozen_time: 37 | assert token.time_left_str == "30m" 38 | 39 | frozen_time.tick(10 * 60 + 5) 40 | assert token.time_left_str == "19m 55.0s" 41 | 42 | frozen_time.tick(20 * 60) 43 | assert token.time_left_str == "Expired" 44 | 45 | @freezegun.freeze_time("2023-01-01 00:00:00") 46 | def test_repr(self): 47 | token = mock_token("test") 48 | spaces = " " * len("Token(") 49 | expected = ( 50 | "Token(" 51 | + "value=test...,\n" 52 | + spaces 53 | + "name=test,\n" 54 | + spaces 55 | + "expires in basically forever" 56 | + "\n)" 57 | ) 58 | assert repr(token) == expected 59 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | pytest_plugins = [ 2 | "tests.fixtures.json", 3 | "tests.fixtures.constants", 4 | "tests.fixtures.config", 5 | ] 6 | -------------------------------------------------------------------------------- /tests/fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/fixtures/__init__.py -------------------------------------------------------------------------------- /tests/fixtures/config.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import pathlib 3 | import tempfile 4 | 5 | import pytest 6 | 7 | config_path = pathlib.Path(__file__).parent / "config_files" 8 | 9 | 10 | @pytest.fixture 11 | def extra_tokens() -> str: 12 | return str(config_path / ".extra_tokens") 13 | 14 | 15 | @pytest.fixture 16 | def no_data() -> str: 17 | return str(config_path / ".no_data") 18 | 19 | 20 | @pytest.fixture 21 | def no_tokens_section() -> str: 22 | return str(config_path / ".no_tokens_section") 23 | 24 | 25 | @pytest.fixture 26 | def valid() -> str: 27 | return str(config_path / ".valid") 28 | 29 | 30 | @pytest.fixture 31 | def valid_with_ftoken() -> str: 32 | return str(config_path / ".valid_with_ftoken") 33 | 34 | 35 | @pytest.fixture 36 | def valid_with_ftoken_list() -> str: 37 | return str(config_path / ".valid_with_ftoken_list") 38 | 39 | 40 | @pytest.fixture 41 | def all_path() -> str: 42 | return str(config_path / ".all") 43 | 44 | 45 | @pytest.fixture 46 | def expected_all() -> str: 47 | return str(config_path / ".expected_all") 48 | 49 | 50 | @pytest.fixture 51 | def s3s_config() -> str: 52 | return str(config_path / "s3sconfig.txt") 53 | 54 | 55 | @pytest.fixture 56 | def all_config(all_path) -> configparser.ConfigParser: 57 | config = configparser.ConfigParser() 58 | config.read(all_path) 59 | return config 60 | 61 | 62 | @pytest.fixture 63 | def temp_file() -> str: 64 | with tempfile.NamedTemporaryFile() as f: 65 | yield f.name 66 | -------------------------------------------------------------------------------- /tests/fixtures/config_files/.all: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | extra_token = test_extra_token 6 | 7 | [data] 8 | country = US 9 | language = en-US 10 | 11 | [options] 12 | user_agent = test_user_agent 13 | f_gen = test_f_token_url0, test_f_token_url1, test_f_token_url2 -------------------------------------------------------------------------------- /tests/fixtures/config_files/.expected_all: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [options] 7 | user_agent = test_user_agent 8 | f_token_url = test_f_token_url0,test_f_token_url1,test_f_token_url2 9 | language = en-US 10 | country = US 11 | 12 | [unknown] 13 | extra_token = test_extra_token -------------------------------------------------------------------------------- /tests/fixtures/config_files/.extra_tokens: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | extra_token = test_extra_token 6 | 7 | [data] 8 | country = US 9 | language = en-US 10 | 11 | [options] 12 | user_agent = test_user_agent -------------------------------------------------------------------------------- /tests/fixtures/config_files/.no_data: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [options] 7 | user_agent = test_user_agent -------------------------------------------------------------------------------- /tests/fixtures/config_files/.no_tokens_section: -------------------------------------------------------------------------------- 1 | [tokens_] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [data] 7 | country = US 8 | language = en-US 9 | 10 | [options] 11 | user_agent = test_user_agent -------------------------------------------------------------------------------- /tests/fixtures/config_files/.valid: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [data] 7 | country = US 8 | language = en-US 9 | 10 | [options] 11 | user_agent = test_user_agent -------------------------------------------------------------------------------- /tests/fixtures/config_files/.valid_with_ftoken: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [data] 7 | country = US 8 | language = en-US 9 | 10 | [options] 11 | user_agent = test_user_agent 12 | f_token_url = test_f_token_url -------------------------------------------------------------------------------- /tests/fixtures/config_files/.valid_with_ftoken_list: -------------------------------------------------------------------------------- 1 | [tokens] 2 | session_token = test_session_token 3 | gtoken = test_gtoken 4 | bullet_token = test_bullet_token 5 | 6 | [data] 7 | country = US 8 | language = en-US 9 | 10 | [options] 11 | user_agent = test_user_agent 12 | f_token_url = test_f_token_url0, test_f_token_url1 -------------------------------------------------------------------------------- /tests/fixtures/config_files/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/fixtures/config_files/__init__.py -------------------------------------------------------------------------------- /tests/fixtures/config_files/s3sconfig.txt: -------------------------------------------------------------------------------- 1 | { 2 | "api_key": "test_api_key", 3 | "acc_loc": "en-US|US", 4 | "gtoken": "test_gtoken", 5 | "bullettoken": "test_bullet_token", 6 | "session_token": "test_session_token", 7 | "f_gen": "test_f_token_url", 8 | "app_user_agent": "test_user_agent" 9 | } -------------------------------------------------------------------------------- /tests/fixtures/constants.py: -------------------------------------------------------------------------------- 1 | import datetime as dt 2 | 3 | import pytest 4 | 5 | 6 | @pytest.fixture 7 | def urand36() -> bytes: 8 | return ( 9 | b"\xe1\t%\x8c\x15\x7f`\xd9\xc6@\xb59\xea1\n\x93\xdf\x9c\xaa1" 10 | b"\x17\xaf\x19f|\xe8\xa0l\xce\xef\x9f\xea\xe8\xc3\xfb\xcb" 11 | ) 12 | 13 | 14 | @pytest.fixture 15 | def urand36_expected() -> bytes: 16 | return b"4QkljBV_YNnGQLU56jEKk9-cqjEXrxlmfOigbM7vn-row_vL" 17 | 18 | 19 | @pytest.fixture 20 | def urand32_expected() -> bytes: 21 | return b"4QkljBV_YNnGQLU56jEKk9-cqjEXrxlmfOigbM7vn-o" 22 | 23 | 24 | @pytest.fixture 25 | def test_session_token() -> str: 26 | return "test_session_token" 27 | 28 | 29 | @pytest.fixture 30 | def timestamp() -> int: 31 | return 1234567890 32 | 33 | 34 | @pytest.fixture 35 | def timestamp_datetime(timestamp: int) -> dt.datetime: 36 | return dt.datetime.fromtimestamp(timestamp) # 2009-02-13 23:31:30 37 | 38 | 39 | @pytest.fixture 40 | def timestamp_datetime_str(timestamp_datetime: dt.datetime) -> str: 41 | return timestamp_datetime.strftime("%Y-%m-%d %H:%M:%S") 42 | -------------------------------------------------------------------------------- /tests/fixtures/linear_json.csv: -------------------------------------------------------------------------------- 1 | a,b,c,c;0,c;1.d,c;1.e 2 | 1,2,,,3,4 -------------------------------------------------------------------------------- /tests/fixtures/linear_json_with_commas.csv: -------------------------------------------------------------------------------- 1 | a,"b,",c,c;0,"c;1.d,",c;1.e 2 | 1,2,,,3,4 -------------------------------------------------------------------------------- /tests/mock.py: -------------------------------------------------------------------------------- 1 | class MockResponse: 2 | def __init__( 3 | self, 4 | status_code: int, 5 | text: str = "", 6 | json: dict = {}, 7 | url: str = "", 8 | ) -> None: 9 | self._status_code = status_code 10 | self.status_code_counter = 0 11 | self._text = text 12 | self.text_counter = 0 13 | self._json = json 14 | self.json_counter = 0 15 | self._url = url 16 | self.url_counter = 0 17 | 18 | @property 19 | def status_code(self): 20 | self.status_code_counter += 1 21 | return self._status_code 22 | 23 | @property 24 | def text(self): 25 | self.text_counter += 1 26 | return self._text 27 | 28 | def json(self): 29 | self.json_counter += 1 30 | return self._json 31 | 32 | @property 33 | def url(self): 34 | self.url_counter += 1 35 | return self._url 36 | 37 | 38 | class MockNSO: 39 | def __init__(self) -> None: 40 | self._mocked = True 41 | self._session_token = None 42 | self._user_info = None 43 | self._gtoken = None 44 | self._invalid_tokens = [] 45 | self._state = b"test_state" 46 | self._verifier = b"test_verifier" 47 | 48 | @property 49 | def session_token(self): 50 | return self._session_token 51 | 52 | @property 53 | def state(self): 54 | return self._state 55 | 56 | @property 57 | def verifier(self): 58 | return self._verifier 59 | 60 | def get_gtoken(self, *args) -> str: 61 | if "gtoken" in self._invalid_tokens: 62 | return "" 63 | 64 | self._gtoken = "test_gtoken" 65 | self._user_info = { 66 | "country": "test_country", 67 | "language": "test_language", 68 | } 69 | return self._gtoken 70 | 71 | def get_bullet_token(self, *args) -> str: 72 | if "bullet_token" in self._invalid_tokens: 73 | return "" 74 | 75 | return "test_bullet_token" 76 | 77 | @staticmethod 78 | def new_instance(): 79 | return MockNSO() 80 | 81 | def generate_login_url(self, *args) -> str: 82 | return "test_url" 83 | 84 | 85 | class MockEnvironmentManager: 86 | BASE_TOKENS = ["test_key_1", "test_key_2"] 87 | 88 | def __init__(self) -> None: 89 | self._mocked = True 90 | 91 | def get_all(self) -> dict[str, str]: 92 | return {f"test_key_{i}": f"test_value_{i}" for i in range(1, 5)} 93 | 94 | 95 | class MockTokenManager: 96 | def __init__( 97 | self, origin: dict = {"origin": "mock", "data": None}, data: dict = {} 98 | ) -> None: 99 | self._mocked = True 100 | self._origin = origin 101 | self.env_manager = MockEnvironmentManager() 102 | self._data = data 103 | 104 | @staticmethod 105 | def load(): 106 | return MockTokenManager() 107 | 108 | @staticmethod 109 | def from_config_file(*args, **kwargs): 110 | return MockTokenManager() 111 | 112 | def generate_all_tokens(self, *args, **kwargs): 113 | pass 114 | 115 | @property 116 | def data(self): 117 | return self._data 118 | 119 | @property 120 | def origin(self): 121 | return self._origin 122 | 123 | def export_tokens(self): 124 | pass 125 | 126 | 127 | class MockConfigParser: 128 | def __init__(self) -> None: 129 | self._mocked = True 130 | self._sections = {"options": {}} 131 | 132 | def __getitem__(self, key): 133 | return self._sections[key] 134 | 135 | def __setitem__(self, key, value): 136 | self._sections[key] = value 137 | 138 | def __contains__(self, key): 139 | return key in self._sections 140 | 141 | def __iter__(self): 142 | return iter(self._sections) 143 | 144 | def __len__(self): 145 | return len(self._sections) 146 | 147 | def add_section(self, section): 148 | self._sections[section] = {} 149 | 150 | def remove_section(self, section): 151 | del self._sections[section] 152 | 153 | def has_section(self, section): 154 | return section in self._sections 155 | 156 | def options(self, section): 157 | return list(self._sections[section].keys()) 158 | 159 | def remove_option(self, section, option): 160 | del self._sections[section][option] 161 | 162 | 163 | class MockConfig: 164 | def __init__(self, *args, **kwargs) -> None: 165 | self._mocked = True 166 | self.token_manager = MockTokenManager() 167 | 168 | 169 | class MockLinearJSON: 170 | def __init__(self, *args, **kwargs) -> None: 171 | self._mocked = True 172 | self.stringify_calls = 0 173 | 174 | def stringify(self, *args, **kwargs): 175 | self.stringify_calls += 1 176 | return ("test_headers", "test_data") 177 | 178 | 179 | class MockPyArrowTable: 180 | def __init__(self, *args, **kwargs) -> None: 181 | self._mocked = True 182 | 183 | @staticmethod 184 | def from_arrays(*args, **kwargs): 185 | return MockPyArrowTable() 186 | 187 | 188 | class MockQueryResponse: 189 | pass 190 | 191 | 192 | class MockQueryHandler: 193 | def __init__(self, *args, **kwargs) -> None: 194 | self._mocked = True 195 | self._data = None 196 | 197 | @staticmethod 198 | def from_session_token(*args, **kwargs): 199 | return MockQueryHandler() 200 | 201 | @staticmethod 202 | def from_config(*args, **kwargs): 203 | return MockQueryHandler() 204 | 205 | @staticmethod 206 | def from_env(*args, **kwargs): 207 | return MockQueryHandler() 208 | 209 | @staticmethod 210 | def from_s3s_config(*args, **kwargs): 211 | return MockQueryHandler() 212 | 213 | def query(self, *args, **kwargs): 214 | return MockQueryResponse() 215 | -------------------------------------------------------------------------------- /tests/query/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/query/__init__.py -------------------------------------------------------------------------------- /tests/query/configuration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/query/configuration/__init__.py -------------------------------------------------------------------------------- /tests/query/configuration/test_callbacks.py: -------------------------------------------------------------------------------- 1 | from unittest.mock import MagicMock, patch 2 | 3 | import pytest 4 | 5 | from splatnet3_scraper.query.config.callbacks import ( 6 | f_token_url_callback, 7 | log_level_callback, 8 | session_token_callback, 9 | ) 10 | 11 | 12 | class TestCallbacks: 13 | @pytest.mark.parametrize( 14 | "session_token", 15 | [ 16 | "session_token", 17 | None, 18 | ], 19 | ids=[ 20 | "valid", 21 | "invalid", 22 | ], 23 | ) 24 | def test_session_token_callback(self, session_token: str | None) -> None: 25 | if session_token is None: 26 | with pytest.raises(ValueError): 27 | session_token_callback(session_token) 28 | else: 29 | assert session_token_callback(session_token) == session_token 30 | 31 | @pytest.mark.parametrize( 32 | "f_token_url, expected", 33 | [ 34 | ("f_token_url", ["f_token_url"]), 35 | ("f_token_url_1,f_token_url_2", ["f_token_url_1", "f_token_url_2"]), 36 | ( 37 | "f_token_url_1 , f_token_url_2", 38 | ["f_token_url_1", "f_token_url_2"], 39 | ), 40 | (["f_token_url"], ["f_token_url"]), 41 | (None, None), 42 | ], 43 | ids=[ 44 | "valid", 45 | "valid comma separated", 46 | "valid whitespace comma separated", 47 | "valid list", 48 | "invalid", 49 | ], 50 | ) 51 | def test_f_token_url_callback( 52 | self, f_token_url: str | list[str] | None, expected: list[str] | None 53 | ) -> None: 54 | if f_token_url is None: 55 | with pytest.raises(ValueError): 56 | f_token_url_callback(f_token_url) 57 | else: 58 | assert f_token_url_callback(f_token_url) == expected 59 | 60 | @pytest.mark.parametrize( 61 | "log_level, expected", 62 | [ 63 | ("CRITICAL", "CRITICAL"), 64 | ("ERROR", "ERROR"), 65 | ("WARNING", "WARNING"), 66 | ("INFO", "INFO"), 67 | ("DEBUG", "DEBUG"), 68 | ("info", "INFO"), 69 | (None, "INFO"), 70 | ("invalid", None), 71 | ], 72 | ids=[ 73 | "CRITICAL", 74 | "ERROR", 75 | "WARNING", 76 | "INFO", 77 | "DEBUG", 78 | "lowercase", 79 | "default", 80 | "invalid", 81 | ], 82 | ) 83 | def test_log_level_callback( 84 | self, log_level: str | None, expected: str | None 85 | ) -> None: 86 | if log_level == "invalid": 87 | with pytest.raises(ValueError): 88 | log_level_callback(log_level) 89 | else: 90 | assert log_level_callback(log_level) == expected 91 | -------------------------------------------------------------------------------- /tests/query/configuration/test_config_option.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | import pytest 4 | 5 | from splatnet3_scraper.query.config.config_option import ConfigOption 6 | 7 | 8 | def callback(value: str | None) -> str | None: 9 | return value 10 | 11 | 12 | def callback_add_one(value: str) -> str: 13 | return str(int(value) + 1) 14 | 15 | 16 | class TestConfigOption: 17 | def test_option(self) -> None: 18 | 19 | option = ConfigOption( 20 | name="test", 21 | default=True, 22 | deprecated_names=["test2"], 23 | deprecated_section="test3", 24 | callback=callback, 25 | section="test4", 26 | env_var="test5", 27 | env_prefix="test6", 28 | ) 29 | assert option.name == "test" 30 | assert option.default == True 31 | assert option.deprecated_names == ["test2"] 32 | assert option.deprecated_section == "test3" 33 | assert option.callback == callback 34 | assert option.section == "test4" 35 | assert option.env_var == "test5" 36 | assert option.env_prefix == "test6" 37 | assert option.value is None 38 | 39 | def test_env_key(self) -> None: 40 | option = ConfigOption( 41 | name="test", 42 | default=True, 43 | deprecated_names=["test2"], 44 | deprecated_section="test3", 45 | callback=None, 46 | section="test4", 47 | env_var="test5", 48 | env_prefix="test6", 49 | ) 50 | assert option.env_key == "test6_test5" 51 | option.env_prefix = None 52 | assert option.env_key == "test5" 53 | option.env_var = None 54 | assert option.env_key is None 55 | 56 | @pytest.mark.parametrize( 57 | "callback", 58 | [ 59 | None, 60 | callback_add_one, 61 | callback, 62 | ], 63 | ids=[ 64 | "No callback", 65 | "With transform callback", 66 | "With callback", 67 | ], 68 | ) 69 | @pytest.mark.parametrize( 70 | "value", 71 | [ 72 | None, 73 | "1", 74 | ], 75 | ids=[ 76 | "No value", 77 | "With value", 78 | ], 79 | ) 80 | @pytest.mark.parametrize( 81 | "default", 82 | [ 83 | None, 84 | "3", 85 | ], 86 | ids=[ 87 | "No default", 88 | "With default", 89 | ], 90 | ) 91 | def test_set_value( 92 | self, 93 | callback: Callable | None, 94 | value: str | None, 95 | default: str | None, 96 | ) -> None: 97 | option = ConfigOption( 98 | name="test", 99 | default=default, 100 | deprecated_names=["test2"], 101 | deprecated_section="test3", 102 | callback=callback, 103 | section="test4", 104 | env_var="test5", 105 | env_prefix="test6", 106 | ) 107 | option.set_value(value) 108 | if callback is None: 109 | assert option.value == value or default 110 | elif value is None and default is None: 111 | assert option.value is None 112 | elif value is None: 113 | assert option.value == default 114 | else: 115 | assert option.value == callback(value) or default 116 | 117 | @pytest.mark.parametrize( 118 | "value", 119 | [ 120 | None, 121 | "1", 122 | ], 123 | ids=[ 124 | "No value", 125 | "With value", 126 | ], 127 | ) 128 | @pytest.mark.parametrize( 129 | "default", 130 | [ 131 | None, 132 | "3", 133 | ], 134 | ids=[ 135 | "No default", 136 | "With default", 137 | ], 138 | ) 139 | @pytest.mark.parametrize( 140 | "env_var", 141 | [ 142 | None, 143 | "test", 144 | ], 145 | ids=[ 146 | "No env var", 147 | "With env var", 148 | ], 149 | ) 150 | def test_get_value( 151 | self, 152 | value: str | None, 153 | default: str | None, 154 | env_var: str | None, 155 | monkeypatch: pytest.MonkeyPatch, 156 | ) -> None: 157 | option = ConfigOption( 158 | name="test", 159 | default=default, 160 | env_var="TEST_ENV_VAR", 161 | ) 162 | if value is not None: 163 | option.set_value(value) 164 | 165 | with monkeypatch.context() as m: 166 | if env_var is not None: 167 | m.setenv("TEST_ENV_VAR", env_var) 168 | if (value is None) and (default is None) and (env_var is None): 169 | with pytest.raises(ValueError): 170 | option.get_value() 171 | return 172 | 173 | return_value = option.get_value() 174 | if value is not None: 175 | assert return_value == value 176 | elif env_var is not None: 177 | assert return_value == env_var 178 | assert option.value == env_var 179 | else: 180 | assert return_value == default 181 | 182 | def test_set_prefix(self) -> None: 183 | option = ConfigOption( 184 | name="test", 185 | default=True, 186 | deprecated_names=["test2"], 187 | deprecated_section="test3", 188 | callback=callback, 189 | section="test4", 190 | env_var="test5", 191 | env_prefix="test6", 192 | ) 193 | assert option.env_prefix == "test6" 194 | option.set_prefix("test7") 195 | assert option.env_prefix == "test7" 196 | -------------------------------------------------------------------------------- /tests/scraper/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cesaregarza/SplatNet3_Scraper/cb2ddf76ab191c13aa088dfbdfc7ef3435c202b7/tests/scraper/__init__.py -------------------------------------------------------------------------------- /tests/scraper/test_query_map.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from splatnet3_scraper.scraper.query_map import QueryMap 4 | 5 | 6 | class TestQueryMap: 7 | def test_get(self): 8 | # Valid 9 | assert QueryMap.get("ANARCHY") == QueryMap.ANARCHY 10 | # lowercase 11 | assert QueryMap.get("anarchy") == QueryMap.ANARCHY 12 | # Invalid 13 | with pytest.raises(AttributeError): 14 | QueryMap.get("invalid") 15 | -------------------------------------------------------------------------------- /tests/test_misc.py: -------------------------------------------------------------------------------- 1 | # This does not test the actual functionality of the code. Anything that needs 2 | # some sort of assurance before pushing to production should be tested here. 3 | import re 4 | 5 | import pytest 6 | 7 | import splatnet3_scraper 8 | 9 | 10 | @pytest.mark.production 11 | def test_version(): 12 | # Make sure the version in the toml file matches the version in the code. 13 | with open("pyproject.toml") as f: 14 | lines = f.readlines() 15 | 16 | version_line = [str(line) for line in lines if "version" in str(line)][0] 17 | version = re.search(r"\d+\.\d+\.\d+", version_line).group(0) 18 | assert version == splatnet3_scraper.__version__ 19 | 20 | 21 | def test_slushie(): 22 | # This test exists to satisfy Slushie's need for a nice round 400 tests 23 | # rather than 399. 24 | assert True 25 | --------------------------------------------------------------------------------