Skip to content

Commit 84ac426

Browse files
committed
update README; typing
1 parent 24e9b5f commit 84ac426

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

CHANGELOG.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66

77
## [0.2.0] - 2023-03-01
88

9+
### Added
10+
- `QueryResult.columnHeaders` now has a corresponding `TypedDict` for `ColumnHeader`.
11+
- Acts the same as before but can have better feedback for things like linters.
12+
- Type annotation for the scalar values in `QueryResult.rows`
13+
914
### Changes
1015
- Updated for SlyAPI 0.4.3
11-
- Awaiting `YouTubeAnalytics` is not longer necessary
16+
- Awaiting `YouTubeAnalytics` is no longer necessary
17+
- Passing scopes to `YouTubeAnalytics` is no longer necessary
1218
- Methods now take `T|set[T]` for enum parameters
1319
- `Dimensions` and `Metrics` are now just plain enums
14-
- the `+` operator has been overloaded to make a `set`
20+
- the `+` operator has been overloaded to make a `set`, so they can be used like before.
1521

1622
## [0.1.0] - 2022-02-26
1723

README.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# ![sly logo](https://raw.githubusercontent.com/dunkyl/SlyMeta/main/sly%20logo.svg) Sly YTAAPI for Python
22

3-
> 🚧 **This library is an early work in progress! Breaking changes may be frequent.**
4-
53
> 🐍 For Python 3.10+
64
75
## No boilerplate, *async* and *typed* Youtube Analytics API access. 😋
@@ -42,3 +40,17 @@ async def main():
4240

4341
asyncio.run(main())
4442
```
43+
44+
---
45+
46+
Example CLI usage for getting authorized:
47+
48+
```sh
49+
# WINDOWS
50+
py -m SlyYTAAPI grant
51+
# MacOS or Linux
52+
python3 -m SlyYTAAPI grant
53+
```
54+
55+
Granting credentials requires a Google Cloud Console account and JSON file.
56+
Please see https://docs.dunkyl.net/SlyAPI-Python/tutorial/oauth2.html for more information.

src/SlyYTAAPI/analytics.py

+25-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from datetime import date, timedelta
33
import json, csv
44
from enum import Enum
5-
from typing import Any, TypeVar
5+
from typing import Any, TypeVar, Literal, TypedDict
66
from SlyAPI import *
77

88
def makeFilters(filters: dict[str, Any]) -> str:
@@ -48,11 +48,20 @@ class Metrics(Enum):
4848
def __add__(self: 'Metrics', other: 'Metrics|set[Metrics]') -> _AddOperator_Set['Metrics']:
4949
return _AddOperator_Set((self,)) + other
5050

51+
class ColumnHeader(TypedDict):
52+
'From https://developers.google.com/youtube/analytics/v2/reference/reports/query'
53+
name: str
54+
columnType: Literal['DIMENSION'] | Literal['METRIC']
55+
dataType: str
56+
5157
@dataclass
5258
class QueryResult:
59+
'''
60+
Table of data returned by YouTube Analytics API.
61+
From https://developers.google.com/youtube/analytics/v2/reference/reports/query'''
5362
kind: str
54-
columnHeaders: list[dict[str, str]] # { "name": ..., "columnType": ..., "dataType": ... }
55-
rows: list[list[Any]]
63+
columnHeaders: list[ColumnHeader]
64+
rows: list[list[int|str|float|bool|None]]
5665

5766
def saveJSON(self, path: str):
5867
with open(path, mode='w', encoding='utf8') as f:
@@ -80,7 +89,19 @@ class YouTubeAnalytics(WebAPI):
8089

8190
channel_id: str
8291

83-
def __init__(self, channel_id: str, auth: OAuth2):
92+
def __init__(self, channel_id: str, auth_or_app: OAuth2|str, user: str|None=None, _scopes: Any|None=None):
93+
if user is not None:
94+
user_ = OAuth2User.from_json_file(user)
95+
else:
96+
user_ = None
97+
if isinstance(auth_or_app, str):
98+
app = OAuth2App.from_json_file(auth_or_app)
99+
if user_ is None:
100+
raise ValueError('user must be specified when auth_or_app is a file path')
101+
auth = OAuth2(app, user_)
102+
else:
103+
auth = auth_or_app
104+
84105
super().__init__(auth)
85106
self.channel_id = channel_id
86107

0 commit comments

Comments
 (0)