playerdatapy 1.8.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- playerdatapy-1.8.1/.github/workflows/ci.yml +38 -0
- playerdatapy-1.8.1/.github/workflows/lint.yml +35 -0
- playerdatapy-1.8.1/.github/workflows/publish.yml +51 -0
- playerdatapy-1.8.1/.github/workflows/release.yml +34 -0
- playerdatapy-1.8.1/.github/workflows/test.yml +32 -0
- playerdatapy-1.8.1/.gitignore +24 -0
- playerdatapy-1.8.1/.releaserc.json +34 -0
- playerdatapy-1.8.1/CODEOWNERS +1 -0
- playerdatapy-1.8.1/LICENSE +21 -0
- playerdatapy-1.8.1/PKG-INFO +128 -0
- playerdatapy-1.8.1/README.md +107 -0
- playerdatapy-1.8.1/examples/direct/README.md +117 -0
- playerdatapy-1.8.1/examples/direct/ball/raw_data_example.py +215 -0
- playerdatapy-1.8.1/examples/direct/example_use.ipynb +285 -0
- playerdatapy-1.8.1/examples/direct/queries/club_sessions_filtered_by_time_range.graphql +7 -0
- playerdatapy-1.8.1/examples/direct/queries/session_details.graphql +19 -0
- playerdatapy-1.8.1/examples/direct/queries/session_metrics.graphql +66 -0
- playerdatapy-1.8.1/examples/direct/queries/session_participations_urls.graphql +8 -0
- playerdatapy-1.8.1/examples/direct/quick_start.py +54 -0
- playerdatapy-1.8.1/examples/pydantic/README.md +156 -0
- playerdatapy-1.8.1/examples/pydantic/ball/raw_data_example.py +173 -0
- playerdatapy-1.8.1/examples/pydantic/example_use.ipynb +306 -0
- playerdatapy-1.8.1/examples/pydantic/queries/club_sessions.py +9 -0
- playerdatapy-1.8.1/examples/pydantic/queries/club_sessions_filtered_by_time_range.py +16 -0
- playerdatapy-1.8.1/examples/pydantic/queries/session_ball_data.py +24 -0
- playerdatapy-1.8.1/examples/pydantic/queries/session_details.py +27 -0
- playerdatapy-1.8.1/examples/pydantic/queries/session_metrics.py +80 -0
- playerdatapy-1.8.1/examples/pydantic/queries/session_participations_urls.py +14 -0
- playerdatapy-1.8.1/examples/pydantic/quick_start.py +38 -0
- playerdatapy-1.8.1/examples/raw_data_utils/url_to_csv.py +152 -0
- playerdatapy-1.8.1/playerdatapy/__init__.py +294 -0
- playerdatapy-1.8.1/playerdatapy/async_base_client.py +375 -0
- playerdatapy-1.8.1/playerdatapy/auth/authorisation_code_flow.py +19 -0
- playerdatapy-1.8.1/playerdatapy/auth/authorisation_code_flow_base.py +48 -0
- playerdatapy-1.8.1/playerdatapy/auth/authorisation_code_flow_pcke.py +12 -0
- playerdatapy-1.8.1/playerdatapy/auth/base_flow.py +38 -0
- playerdatapy-1.8.1/playerdatapy/auth/callback_handler.py +53 -0
- playerdatapy-1.8.1/playerdatapy/auth/client_credentials_flow.py +40 -0
- playerdatapy-1.8.1/playerdatapy/auth/server.py +42 -0
- playerdatapy-1.8.1/playerdatapy/base_model.py +30 -0
- playerdatapy-1.8.1/playerdatapy/base_operation.py +156 -0
- playerdatapy-1.8.1/playerdatapy/constants.py +1 -0
- playerdatapy-1.8.1/playerdatapy/custom_fields.py +19662 -0
- playerdatapy-1.8.1/playerdatapy/custom_mutations.py +1820 -0
- playerdatapy-1.8.1/playerdatapy/custom_queries.py +618 -0
- playerdatapy-1.8.1/playerdatapy/custom_typing_fields.py +1927 -0
- playerdatapy-1.8.1/playerdatapy/enums.py +544 -0
- playerdatapy-1.8.1/playerdatapy/exceptions.py +85 -0
- playerdatapy-1.8.1/playerdatapy/gqlauth.py +73 -0
- playerdatapy-1.8.1/playerdatapy/gqlclient.py +109 -0
- playerdatapy-1.8.1/playerdatapy/input_types.py +709 -0
- playerdatapy-1.8.1/playerdatapy/playerdata_api.py +42 -0
- playerdatapy-1.8.1/playerdatapy/py.typed +0 -0
- playerdatapy-1.8.1/pyproject.toml +51 -0
- playerdatapy-1.8.1/scripts/fix_imports.py +33 -0
- playerdatapy-1.8.1/scripts/get_auth_token.py +24 -0
- playerdatapy-1.8.1/tests/__init__.py +0 -0
- playerdatapy-1.8.1/tests/auth/__init__.py +0 -0
- playerdatapy-1.8.1/tests/auth/test_authorisation_code_flow.py +50 -0
- playerdatapy-1.8.1/tests/auth/test_authorisation_code_flow_base.py +141 -0
- playerdatapy-1.8.1/tests/auth/test_authorisation_code_flow_pcke.py +54 -0
- playerdatapy-1.8.1/tests/auth/test_base_flow.py +136 -0
- playerdatapy-1.8.1/tests/auth/test_client_credentials_flow.py +119 -0
- playerdatapy-1.8.1/tests/test_gqlauth.py +170 -0
- playerdatapy-1.8.1/tests/test_playerdata_api.py +283 -0
- playerdatapy-1.8.1/uv.lock +1226 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: PlayerDataPy CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened, ready_for_review]
|
|
6
|
+
push:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Lint
|
|
16
|
+
secrets: inherit
|
|
17
|
+
uses: "./.github/workflows/lint.yml"
|
|
18
|
+
|
|
19
|
+
test:
|
|
20
|
+
name: Test
|
|
21
|
+
secrets: inherit
|
|
22
|
+
uses: "./.github/workflows/test.yml"
|
|
23
|
+
|
|
24
|
+
release:
|
|
25
|
+
name: Release
|
|
26
|
+
secrets: inherit
|
|
27
|
+
needs: [lint, test]
|
|
28
|
+
uses: "./.github/workflows/release.yml"
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
name: Publish playerDatapy Python Package
|
|
32
|
+
secrets: inherit
|
|
33
|
+
needs: release
|
|
34
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
35
|
+
uses: "./.github/workflows/publish.yml"
|
|
36
|
+
with:
|
|
37
|
+
new_release_published: ${{ needs.release.outputs.new_release_published }}
|
|
38
|
+
new_release_version: ${{ needs.release.outputs.new_release_version }}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: PlayerDataPy Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call: {}
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
lint:
|
|
8
|
+
name: Lint
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
id: setup-uv
|
|
22
|
+
uses: astral-sh/setup-uv@v6.6.1
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
cache-suffix: '-venv-lint'
|
|
26
|
+
activate-environment: true
|
|
27
|
+
|
|
28
|
+
- name: Install Dependencies
|
|
29
|
+
run: uv sync --extra dev --locked
|
|
30
|
+
|
|
31
|
+
- name: Lint Check (Ruff)
|
|
32
|
+
run: uv run --no-sync ruff check .
|
|
33
|
+
|
|
34
|
+
- name: Format Check (Ruff)
|
|
35
|
+
run: uv run --no-sync ruff format --check .
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Publish Python
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
new_release_published:
|
|
7
|
+
description: 'Whether a new release has been published'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
new_release_version:
|
|
11
|
+
description: 'The latest release version'
|
|
12
|
+
required: true
|
|
13
|
+
type: string
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
publish:
|
|
17
|
+
name: Publish Python Package
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
id-token: write
|
|
22
|
+
|
|
23
|
+
environment:
|
|
24
|
+
name: pypi
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
|
|
29
|
+
- uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: '3.12'
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@v7.2.1
|
|
35
|
+
with:
|
|
36
|
+
enable-cache: true
|
|
37
|
+
cache-suffix: '-publish'
|
|
38
|
+
activate-environment: true
|
|
39
|
+
|
|
40
|
+
- name: Apply Semantic Version
|
|
41
|
+
if: ${{ inputs.new_release_published == 'true' }}
|
|
42
|
+
run: uv version ${{ inputs.new_release_version }}
|
|
43
|
+
|
|
44
|
+
- name: Build
|
|
45
|
+
if: ${{ inputs.new_release_published == 'true' }}
|
|
46
|
+
run: uv build
|
|
47
|
+
|
|
48
|
+
- name: Publish
|
|
49
|
+
if: ${{ inputs.new_release_published == 'true' }}
|
|
50
|
+
run: uv publish --trusted-publishing always
|
|
51
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: PlayerDataPy Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
outputs:
|
|
6
|
+
new_release_published:
|
|
7
|
+
value: ${{ jobs.release.outputs.new_release_published }}
|
|
8
|
+
new_release_version:
|
|
9
|
+
value: ${{ jobs.release.outputs.new_release_version }}
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
issues: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
release:
|
|
18
|
+
name: Release
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
|
|
26
|
+
- name: Semantic Release
|
|
27
|
+
id: semantic-release
|
|
28
|
+
uses: cycjimmy/semantic-release-action@v4
|
|
29
|
+
env:
|
|
30
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
|
|
32
|
+
outputs:
|
|
33
|
+
new_release_published: ${{ steps.semantic-release.outputs.new_release_published }}
|
|
34
|
+
new_release_version: ${{ steps.semantic-release.outputs.new_release_version }}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: PlayerDataPy Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call: {}
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
name: Test
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
id: setup-uv
|
|
22
|
+
uses: astral-sh/setup-uv@v6.6.1
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
cache-suffix: '-venv-test'
|
|
26
|
+
activate-environment: true
|
|
27
|
+
|
|
28
|
+
- name: Install Dependencies
|
|
29
|
+
run: uv sync --extra dev --locked
|
|
30
|
+
|
|
31
|
+
- name: Run Tests
|
|
32
|
+
run: uv run --no-sync pytest
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
|
|
3
|
+
.token
|
|
4
|
+
.vscode
|
|
5
|
+
.vscode
|
|
6
|
+
.python-version
|
|
7
|
+
key.json
|
|
8
|
+
.DS_Store
|
|
9
|
+
venv
|
|
10
|
+
.venv
|
|
11
|
+
.idea
|
|
12
|
+
__pycache__
|
|
13
|
+
__PYCACHE__
|
|
14
|
+
.pytest_cache
|
|
15
|
+
.mypy_cache
|
|
16
|
+
.ipynb_checkpoints
|
|
17
|
+
*.egg-info/
|
|
18
|
+
*.pyc
|
|
19
|
+
*.mp4
|
|
20
|
+
*.rrd
|
|
21
|
+
*.edgeblob
|
|
22
|
+
*.glb
|
|
23
|
+
.coverage
|
|
24
|
+
.token
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": ["main"],
|
|
3
|
+
"plugins": [
|
|
4
|
+
[
|
|
5
|
+
"@semantic-release/commit-analyzer",
|
|
6
|
+
{
|
|
7
|
+
"preset": "angular",
|
|
8
|
+
"releaseRules": [
|
|
9
|
+
{
|
|
10
|
+
"type": "chore",
|
|
11
|
+
"release": "patch"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "feat",
|
|
15
|
+
"release": "minor"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "fix",
|
|
19
|
+
"release": "patch"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"@semantic-release/release-notes-generator",
|
|
25
|
+
[
|
|
26
|
+
"@semantic-release/github",
|
|
27
|
+
{
|
|
28
|
+
"successComment": false,
|
|
29
|
+
"failComment": false,
|
|
30
|
+
"failTitle": false
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @playerdata/data-analysis
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PlayerData
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: playerdatapy
|
|
3
|
+
Version: 1.8.1
|
|
4
|
+
Summary: Python client for the PlayerData GraphQL API
|
|
5
|
+
Author-email: PlayerData Engineering <dev@playerdata.com>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: <3.14,>=3.10
|
|
8
|
+
Requires-Dist: graphql-core>=3.2.0
|
|
9
|
+
Requires-Dist: httpx>=0.24.0
|
|
10
|
+
Requires-Dist: oauthlib>=3.2.0
|
|
11
|
+
Requires-Dist: polars>=1.37.1
|
|
12
|
+
Requires-Dist: pydantic>=2.0.0
|
|
13
|
+
Requires-Dist: requests-oauthlib>=2.0.0
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: ariadne-codegen>=0.17.0; extra == 'dev'
|
|
16
|
+
Requires-Dist: ipykernel>=7.1.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest>=8.4.2; extra == 'dev'
|
|
19
|
+
Requires-Dist: ruff>=0.14.14; extra == 'dev'
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# PlayerDataPy
|
|
23
|
+
A python package for interacting with the PlayerData GraphQL API.
|
|
24
|
+
|
|
25
|
+
## Folder Structure
|
|
26
|
+
- `playerdata_api`: The main package for interacting with the PlayerData API.
|
|
27
|
+
- `gqlauth`: The main package for authenticating with the PlayerData API.
|
|
28
|
+
- `gqlclient`: The main package for interacting with the PlayerData GraphQL API.
|
|
29
|
+
- `custom_queries`: Custom queries for the PlayerData GraphQL API.
|
|
30
|
+
- `custom_mutations`: Custom mutations for the PlayerData GraphQL API.
|
|
31
|
+
- `custom_fields`: Custom fields for the PlayerData GraphQL API.
|
|
32
|
+
- `input_types`: Input types for the PlayerData GraphQL API.
|
|
33
|
+
- `enums`: Enums for the PlayerData GraphQL API.
|
|
34
|
+
- `custom_typing_fields`: Custom typing fields for the PlayerData GraphQL API.
|
|
35
|
+
- `custom_responses`: Custom responses for the PlayerData GraphQL API.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
uv is the tool we use to build and manage the `playerdatapy` Python package.
|
|
40
|
+
|
|
41
|
+
Make sure you install uv using [pipx](https://docs.astral.sh/uv/getting-started/installation/#pypi) or the [official installer](https://docs.astral.sh/uv/getting-started/installation/#standalone-installer). Installing with pip or other methods will lead to unexpected behavior.
|
|
42
|
+
|
|
43
|
+
We recommend using the [official installer](https://docs.astral.sh/uv/getting-started/installation/#standalone-installer).
|
|
44
|
+
|
|
45
|
+
Then you can install the required dependencies, in a virtual environment if required.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv sync
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
To use the GraphqlClient, you need to provide your client id, this will be provided to you by PlayerData.
|
|
54
|
+
To request API credentials, please contact the PlayerData team at support@playerdata.co.uk.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Option 1: Use generated types with PlayerDataAPI
|
|
58
|
+
|
|
59
|
+
Example usage of this option is provided in the `examples/pydantic/` folder.
|
|
60
|
+
The basic flow is to create a PlayerDataAPI instance, build the query objects using the code-generated Pydantic models (generated by ariadne-codegen), and then call the run_queries method.
|
|
61
|
+
|
|
62
|
+
For more detailed documentation, see [`examples/pydantic/README.md`](examples/pydantic/README.md).
|
|
63
|
+
|
|
64
|
+
To run an example of this option, you can use the following command:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python examples/pydantic/quick_start.py
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
To run this you will need to set the following environment variables or hardcode them in the file:
|
|
71
|
+
```bash
|
|
72
|
+
export CLIENT_ID=your_client_id
|
|
73
|
+
export CLIENT_SECRET=your_client_secret
|
|
74
|
+
export CLUB_ID=your_club_id
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For a more in-depth example, please see the `examples/pydantic/example_use.ipynb` notebook.
|
|
78
|
+
This notebook demonstrates how to use the PlayerData API with Pydantic to query specifics such as session details, session metrics, and raw data.
|
|
79
|
+
|
|
80
|
+
### Option 2: Use the GraphqlClient class directly
|
|
81
|
+
|
|
82
|
+
Example usage of this option is provided in the `examples/direct/` folder.
|
|
83
|
+
The basic flow is to create a GraphqlClient instance, build the query string, and then call the query method.
|
|
84
|
+
|
|
85
|
+
For more detailed documentation, see [`examples/direct/README.md`](examples/direct/README.md).
|
|
86
|
+
|
|
87
|
+
To run an example of this option, you can use the following command:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python examples/direct/quick_start.py
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
To run this you will need to set the following environment variables or hardcode them in the file:
|
|
94
|
+
```bash
|
|
95
|
+
export CLIENT_ID=your_client_id
|
|
96
|
+
export CLIENT_SECRET=your_client_secret
|
|
97
|
+
export CLUB_ID=your_club_id
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Authentication Types
|
|
101
|
+
|
|
102
|
+
These authentication types are set out in the `playerdatapy.gqlauth.AuthenticationType` enum.
|
|
103
|
+
The default authentication type is `AuthenticationType.AUTHORISATION_CODE_FLOW`.
|
|
104
|
+
These authentication types are used to set the authentication type in the `GraphqlAuth` class.
|
|
105
|
+
|
|
106
|
+
### Authorisation Code Flow (PKCE)
|
|
107
|
+
|
|
108
|
+
Authorisation code flow with PKCE is used to authenticate users with non_confidential credentials.
|
|
109
|
+
|
|
110
|
+
### Authorisation Code Flow
|
|
111
|
+
|
|
112
|
+
Authorisation code flow is used to authenticate users with confidential credentials.
|
|
113
|
+
|
|
114
|
+
### Client Credentials Flow
|
|
115
|
+
|
|
116
|
+
Client credentials flow is used to authenticate backend to backend communication.
|
|
117
|
+
|
|
118
|
+
### Updates to the API Fields and Mutations
|
|
119
|
+
|
|
120
|
+
To update the API fields and mutations, you need to set an `AUTH_TOKEN` environment variable.
|
|
121
|
+
This code is auto-generated by Ariadne, so any changes to the API fields and mutations will be reflected in the code.
|
|
122
|
+
|
|
123
|
+
```shell
|
|
124
|
+
export AUTH_TOKEN=f"Bearer {your_auth_token}"
|
|
125
|
+
python -m ariadne-codegen
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This will generate code and update files in the `playerdatapy` package.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# PlayerDataPy
|
|
2
|
+
A python package for interacting with the PlayerData GraphQL API.
|
|
3
|
+
|
|
4
|
+
## Folder Structure
|
|
5
|
+
- `playerdata_api`: The main package for interacting with the PlayerData API.
|
|
6
|
+
- `gqlauth`: The main package for authenticating with the PlayerData API.
|
|
7
|
+
- `gqlclient`: The main package for interacting with the PlayerData GraphQL API.
|
|
8
|
+
- `custom_queries`: Custom queries for the PlayerData GraphQL API.
|
|
9
|
+
- `custom_mutations`: Custom mutations for the PlayerData GraphQL API.
|
|
10
|
+
- `custom_fields`: Custom fields for the PlayerData GraphQL API.
|
|
11
|
+
- `input_types`: Input types for the PlayerData GraphQL API.
|
|
12
|
+
- `enums`: Enums for the PlayerData GraphQL API.
|
|
13
|
+
- `custom_typing_fields`: Custom typing fields for the PlayerData GraphQL API.
|
|
14
|
+
- `custom_responses`: Custom responses for the PlayerData GraphQL API.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
uv is the tool we use to build and manage the `playerdatapy` Python package.
|
|
19
|
+
|
|
20
|
+
Make sure you install uv using [pipx](https://docs.astral.sh/uv/getting-started/installation/#pypi) or the [official installer](https://docs.astral.sh/uv/getting-started/installation/#standalone-installer). Installing with pip or other methods will lead to unexpected behavior.
|
|
21
|
+
|
|
22
|
+
We recommend using the [official installer](https://docs.astral.sh/uv/getting-started/installation/#standalone-installer).
|
|
23
|
+
|
|
24
|
+
Then you can install the required dependencies, in a virtual environment if required.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv sync
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
To use the GraphqlClient, you need to provide your client id, this will be provided to you by PlayerData.
|
|
33
|
+
To request API credentials, please contact the PlayerData team at support@playerdata.co.uk.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Option 1: Use generated types with PlayerDataAPI
|
|
37
|
+
|
|
38
|
+
Example usage of this option is provided in the `examples/pydantic/` folder.
|
|
39
|
+
The basic flow is to create a PlayerDataAPI instance, build the query objects using the code-generated Pydantic models (generated by ariadne-codegen), and then call the run_queries method.
|
|
40
|
+
|
|
41
|
+
For more detailed documentation, see [`examples/pydantic/README.md`](examples/pydantic/README.md).
|
|
42
|
+
|
|
43
|
+
To run an example of this option, you can use the following command:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python examples/pydantic/quick_start.py
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
To run this you will need to set the following environment variables or hardcode them in the file:
|
|
50
|
+
```bash
|
|
51
|
+
export CLIENT_ID=your_client_id
|
|
52
|
+
export CLIENT_SECRET=your_client_secret
|
|
53
|
+
export CLUB_ID=your_club_id
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For a more in-depth example, please see the `examples/pydantic/example_use.ipynb` notebook.
|
|
57
|
+
This notebook demonstrates how to use the PlayerData API with Pydantic to query specifics such as session details, session metrics, and raw data.
|
|
58
|
+
|
|
59
|
+
### Option 2: Use the GraphqlClient class directly
|
|
60
|
+
|
|
61
|
+
Example usage of this option is provided in the `examples/direct/` folder.
|
|
62
|
+
The basic flow is to create a GraphqlClient instance, build the query string, and then call the query method.
|
|
63
|
+
|
|
64
|
+
For more detailed documentation, see [`examples/direct/README.md`](examples/direct/README.md).
|
|
65
|
+
|
|
66
|
+
To run an example of this option, you can use the following command:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
python examples/direct/quick_start.py
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To run this you will need to set the following environment variables or hardcode them in the file:
|
|
73
|
+
```bash
|
|
74
|
+
export CLIENT_ID=your_client_id
|
|
75
|
+
export CLIENT_SECRET=your_client_secret
|
|
76
|
+
export CLUB_ID=your_club_id
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Authentication Types
|
|
80
|
+
|
|
81
|
+
These authentication types are set out in the `playerdatapy.gqlauth.AuthenticationType` enum.
|
|
82
|
+
The default authentication type is `AuthenticationType.AUTHORISATION_CODE_FLOW`.
|
|
83
|
+
These authentication types are used to set the authentication type in the `GraphqlAuth` class.
|
|
84
|
+
|
|
85
|
+
### Authorisation Code Flow (PKCE)
|
|
86
|
+
|
|
87
|
+
Authorisation code flow with PKCE is used to authenticate users with non_confidential credentials.
|
|
88
|
+
|
|
89
|
+
### Authorisation Code Flow
|
|
90
|
+
|
|
91
|
+
Authorisation code flow is used to authenticate users with confidential credentials.
|
|
92
|
+
|
|
93
|
+
### Client Credentials Flow
|
|
94
|
+
|
|
95
|
+
Client credentials flow is used to authenticate backend to backend communication.
|
|
96
|
+
|
|
97
|
+
### Updates to the API Fields and Mutations
|
|
98
|
+
|
|
99
|
+
To update the API fields and mutations, you need to set an `AUTH_TOKEN` environment variable.
|
|
100
|
+
This code is auto-generated by Ariadne, so any changes to the API fields and mutations will be reflected in the code.
|
|
101
|
+
|
|
102
|
+
```shell
|
|
103
|
+
export AUTH_TOKEN=f"Bearer {your_auth_token}"
|
|
104
|
+
python -m ariadne-codegen
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This will generate code and update files in the `playerdatapy` package.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Direct GraphQL Examples
|
|
2
|
+
|
|
3
|
+
This folder contains examples demonstrating how to use PlayerDataPy by directly interacting with the `GraphqlClient` class. This approach gives you full control over GraphQL query strings and is useful when you need fine-grained control or want to use queries from external sources.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The direct approach uses the `GraphqlClient` class to execute raw GraphQL query strings. This method is more flexible but requires you to manually construct GraphQL queries and handle the response structure.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
The simplest way to get started is with the `quick_start.py` example:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python examples/direct/quick_start.py
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Before running, set the following environment variables:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export CLIENT_ID=your_client_id
|
|
21
|
+
export CLIENT_SECRET=your_client_secret
|
|
22
|
+
export CLUB_ID=your_club_id
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Basic Usage Pattern
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from playerdatapy.gqlauth import GraphqlAuth, AuthenticationType
|
|
29
|
+
from playerdatapy.gqlclient import Client
|
|
30
|
+
from playerdatapy.constants import API_BASE_URL
|
|
31
|
+
import asyncio
|
|
32
|
+
|
|
33
|
+
# Authenticate
|
|
34
|
+
auth = GraphqlAuth(
|
|
35
|
+
client_id=CLIENT_ID,
|
|
36
|
+
client_secret=CLIENT_SECRET,
|
|
37
|
+
type=AuthenticationType.CLIENT_CREDENTIALS_FLOW,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Create a Client instance
|
|
41
|
+
client = Client(
|
|
42
|
+
url=f"{API_BASE_URL}/api/graphql",
|
|
43
|
+
headers={"Authorization": f"Bearer {auth._get_authentication_token()}"},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Build your GraphQL query string
|
|
47
|
+
query = """
|
|
48
|
+
query($clubIdEq:ID!,$startTimeGteq:ISO8601DateTime,$endTimeLteq:ISO8601DateTime){
|
|
49
|
+
sessions(filter: {clubIdEq:$clubIdEq, startTimeGteq:$startTimeGteq, endTimeLteq:$endTimeLteq}){
|
|
50
|
+
id
|
|
51
|
+
startTime
|
|
52
|
+
endTime
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
# Define variables
|
|
58
|
+
variables = {
|
|
59
|
+
"clubIdEq": CLUB_ID,
|
|
60
|
+
"startTimeGteq": start_time,
|
|
61
|
+
"endTimeLteq": end_time,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Execute the query
|
|
65
|
+
async def main():
|
|
66
|
+
response = client.execute(query=query, variables=variables)
|
|
67
|
+
result = await client.get_data(response)
|
|
68
|
+
print(result["sessions"])
|
|
69
|
+
|
|
70
|
+
asyncio.run(main())
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Building Queries
|
|
74
|
+
|
|
75
|
+
When building GraphQL queries, you can use the GraphiQL Playground at https://app.playerdata.co.uk/api/graphiql/ to:
|
|
76
|
+
- Test queries interactively
|
|
77
|
+
- Explore the schema
|
|
78
|
+
- Validate query syntax
|
|
79
|
+
- See example queries
|
|
80
|
+
|
|
81
|
+
The playground provides autocomplete and schema documentation to help you build queries efficiently.
|
|
82
|
+
|
|
83
|
+
## Example Query
|
|
84
|
+
|
|
85
|
+
The `quick_start.py` example demonstrates querying sessions filtered by time range:
|
|
86
|
+
|
|
87
|
+
```graphql
|
|
88
|
+
query($clubIdEq:ID!,$startTimeGteq:ISO8601DateTime,$endTimeLteq:ISO8601DateTime){
|
|
89
|
+
sessions(filter: {clubIdEq:$clubIdEq, startTimeGteq:$startTimeGteq, endTimeLteq:$endTimeLteq}){
|
|
90
|
+
id
|
|
91
|
+
startTime
|
|
92
|
+
endTime
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This query:
|
|
98
|
+
- Takes a club ID and time range as variables
|
|
99
|
+
- Filters sessions by club ID and time range
|
|
100
|
+
- Returns session ID, start time, and end time
|
|
101
|
+
|
|
102
|
+
## Authentication Types
|
|
103
|
+
|
|
104
|
+
The examples use `AuthenticationType.CLIENT_CREDENTIALS_FLOW` by default, which is suitable for backend-to-backend communication. You can also use:
|
|
105
|
+
|
|
106
|
+
- `AuthenticationType.AUTHORISATION_CODE_FLOW`: For confidential client credentials
|
|
107
|
+
- `AuthenticationType.AUTHORISATION_CODE_FLOW_PKCE`: For non-confidential client credentials
|
|
108
|
+
|
|
109
|
+
## When to Use Direct GraphQL
|
|
110
|
+
|
|
111
|
+
Use the direct GraphQL approach when:
|
|
112
|
+
- You need full control over query strings
|
|
113
|
+
- You're migrating existing GraphQL queries
|
|
114
|
+
- You want to use queries from external tools or documentation
|
|
115
|
+
- You prefer working with raw GraphQL syntax
|
|
116
|
+
|
|
117
|
+
For type-safe queries with autocomplete support, consider using the [Pydantic examples](../pydantic/) instead.
|