tvpulse 0.1.0__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.
- tvpulse-0.1.0/LICENSE +21 -0
- tvpulse-0.1.0/PKG-INFO +83 -0
- tvpulse-0.1.0/README.md +64 -0
- tvpulse-0.1.0/pyproject.toml +22 -0
- tvpulse-0.1.0/setup.cfg +4 -0
- tvpulse-0.1.0/setup.py +22 -0
- tvpulse-0.1.0/tests/test_client.py +59 -0
- tvpulse-0.1.0/tvpulse/__init__.py +5 -0
- tvpulse-0.1.0/tvpulse/__version__.py +1 -0
- tvpulse-0.1.0/tvpulse/api.py +69 -0
- tvpulse-0.1.0/tvpulse/client.py +81 -0
- tvpulse-0.1.0/tvpulse/exceptions.py +19 -0
- tvpulse-0.1.0/tvpulse/models.py +20 -0
- tvpulse-0.1.0/tvpulse.egg-info/PKG-INFO +83 -0
- tvpulse-0.1.0/tvpulse.egg-info/SOURCES.txt +15 -0
- tvpulse-0.1.0/tvpulse.egg-info/dependency_links.txt +1 -0
- tvpulse-0.1.0/tvpulse.egg-info/top_level.txt +1 -0
tvpulse-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 SDio
|
|
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.
|
tvpulse-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tvpulse
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official TVPulse SDK for Python
|
|
5
|
+
Home-page: https://github.com/sdio/tvpulse-python-sdk
|
|
6
|
+
Author: SDIO
|
|
7
|
+
Author-email: SDIO <dev@sdio.io>
|
|
8
|
+
Project-URL: Homepage, https://github.com/sdio/tvpulse-python-sdk
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/sdio/tvpulse-python-sdk/issues
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.7
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# TVPulse Python SDK
|
|
21
|
+
|
|
22
|
+
The official Python SDK for the TVPulse API.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install tvpulse
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
First, you need to initialize the `Client` with your API key. You can get your API key from the TVPulse UI.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from tvpulse import Client, TVPulseError
|
|
37
|
+
|
|
38
|
+
# Initialize the SDK
|
|
39
|
+
# It's recommended to store your API key in an environment variable.
|
|
40
|
+
api_key = os.environ.get("TVPULSE_API_KEY")
|
|
41
|
+
if not api_key:
|
|
42
|
+
raise ValueError("TVPULSE_API_KEY environment variable not set.")
|
|
43
|
+
|
|
44
|
+
client = Client(api_key=api_key)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Get Data
|
|
48
|
+
|
|
49
|
+
You can use the `get_data` method to retrieve data from the API. This method takes the following arguments:
|
|
50
|
+
|
|
51
|
+
- `searchTypes`: A list of search types to use. Currently, only one search type is supported at a time. Valid search types are `"asr"` and `"ocr"`.
|
|
52
|
+
- `keyword`: The keyword to search for.
|
|
53
|
+
- `streams`: A list of streams to search.
|
|
54
|
+
- `start_date`: The start date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
55
|
+
- `end_date`: The end date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
56
|
+
- `frequency`: The frequency of the search. Valid values are `"hour"` and `"day"`.
|
|
57
|
+
- `score_threshold`: The score threshold for the search. This should be a float between 0 and 1.
|
|
58
|
+
|
|
59
|
+
Here's an example of how to use the `get_data` method:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
try:
|
|
63
|
+
data = client.get_data(
|
|
64
|
+
searchTypes=["asr"],
|
|
65
|
+
keyword="コーヒー",
|
|
66
|
+
streams=["CX", "EX", "NTV", "TBS", "TX"],
|
|
67
|
+
start_date="2025-01-01 00:00:00",
|
|
68
|
+
end_date="2025-01-02 23:59:59",
|
|
69
|
+
frequency="hour",
|
|
70
|
+
score_threshold=0.95
|
|
71
|
+
)
|
|
72
|
+
print(data)
|
|
73
|
+
except TVPulseError as e:
|
|
74
|
+
print(f"An error occurred: {e}")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Error Handling
|
|
78
|
+
|
|
79
|
+
The SDK raises custom exceptions for different types of errors. You can catch these exceptions to handle errors gracefully.
|
|
80
|
+
|
|
81
|
+
- `TVPulseError`: The base class for all SDK errors.
|
|
82
|
+
- `AuthenticationError`: Raised when there is an authentication error (e.g., an invalid API key).
|
|
83
|
+
- `InvalidRequestError`: Raised when the request is invalid (e.g., a missing or invalid parameter).
|
tvpulse-0.1.0/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# TVPulse Python SDK
|
|
2
|
+
|
|
3
|
+
The official Python SDK for the TVPulse API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install tvpulse
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
First, you need to initialize the `Client` with your API key. You can get your API key from the TVPulse UI.
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import os
|
|
17
|
+
from tvpulse import Client, TVPulseError
|
|
18
|
+
|
|
19
|
+
# Initialize the SDK
|
|
20
|
+
# It's recommended to store your API key in an environment variable.
|
|
21
|
+
api_key = os.environ.get("TVPULSE_API_KEY")
|
|
22
|
+
if not api_key:
|
|
23
|
+
raise ValueError("TVPULSE_API_KEY environment variable not set.")
|
|
24
|
+
|
|
25
|
+
client = Client(api_key=api_key)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Get Data
|
|
29
|
+
|
|
30
|
+
You can use the `get_data` method to retrieve data from the API. This method takes the following arguments:
|
|
31
|
+
|
|
32
|
+
- `searchTypes`: A list of search types to use. Currently, only one search type is supported at a time. Valid search types are `"asr"` and `"ocr"`.
|
|
33
|
+
- `keyword`: The keyword to search for.
|
|
34
|
+
- `streams`: A list of streams to search.
|
|
35
|
+
- `start_date`: The start date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
36
|
+
- `end_date`: The end date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
37
|
+
- `frequency`: The frequency of the search. Valid values are `"hour"` and `"day"`.
|
|
38
|
+
- `score_threshold`: The score threshold for the search. This should be a float between 0 and 1.
|
|
39
|
+
|
|
40
|
+
Here's an example of how to use the `get_data` method:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
try:
|
|
44
|
+
data = client.get_data(
|
|
45
|
+
searchTypes=["asr"],
|
|
46
|
+
keyword="コーヒー",
|
|
47
|
+
streams=["CX", "EX", "NTV", "TBS", "TX"],
|
|
48
|
+
start_date="2025-01-01 00:00:00",
|
|
49
|
+
end_date="2025-01-02 23:59:59",
|
|
50
|
+
frequency="hour",
|
|
51
|
+
score_threshold=0.95
|
|
52
|
+
)
|
|
53
|
+
print(data)
|
|
54
|
+
except TVPulseError as e:
|
|
55
|
+
print(f"An error occurred: {e}")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Error Handling
|
|
59
|
+
|
|
60
|
+
The SDK raises custom exceptions for different types of errors. You can catch these exceptions to handle errors gracefully.
|
|
61
|
+
|
|
62
|
+
- `TVPulseError`: The base class for all SDK errors.
|
|
63
|
+
- `AuthenticationError`: Raised when there is an authentication error (e.g., an invalid API key).
|
|
64
|
+
- `InvalidRequestError`: Raised when the request is invalid (e.g., a missing or invalid parameter).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tvpulse"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="SDIO", email="dev@sdio.io" },
|
|
10
|
+
]
|
|
11
|
+
description = "Official TVPulse SDK for Python"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.7"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
"Homepage" = "https://github.com/sdio/tvpulse-python-sdk"
|
|
22
|
+
"Bug Tracker" = "https://github.com/sdio/tvpulse-python-sdk/issues"
|
tvpulse-0.1.0/setup.cfg
ADDED
tvpulse-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='tvpulse',
|
|
5
|
+
version='0.1.0',
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[
|
|
8
|
+
'requests',
|
|
9
|
+
'pydantic',
|
|
10
|
+
],
|
|
11
|
+
author='SDIO',
|
|
12
|
+
author_email='dev@sdio.io',
|
|
13
|
+
description='Official TVPulse SDK for Python',
|
|
14
|
+
long_description=open('README.md').read(),
|
|
15
|
+
long_description_content_type='text/markdown',
|
|
16
|
+
url='https://github.com/sdio/tvpulse-python-sdk',
|
|
17
|
+
classifiers=[
|
|
18
|
+
'Programming Language :: Python :: 3',
|
|
19
|
+
'License :: OSI Approved :: MIT License',
|
|
20
|
+
'Operating System :: OS Independent',
|
|
21
|
+
],
|
|
22
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import MagicMock, patch
|
|
3
|
+
from tvpulse.client import Client
|
|
4
|
+
from tvpulse.exceptions import InvalidRequestError
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestClient(unittest.TestCase):
|
|
8
|
+
|
|
9
|
+
def setUp(self):
|
|
10
|
+
self.api_key = "test_api_key"
|
|
11
|
+
self.client = Client(api_key=self.api_key)
|
|
12
|
+
self.test_params = {
|
|
13
|
+
"keyword": "test",
|
|
14
|
+
"streams": ["TBS"],
|
|
15
|
+
"start_date": "2025-01-01 00:00:00",
|
|
16
|
+
"end_date": "2025-01-01 06:00:00",
|
|
17
|
+
"frequency": "hour",
|
|
18
|
+
"score_threshold": 0.95
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@patch('tvpulse.api.API.search_voice')
|
|
22
|
+
def test_get_data_asr(self, mock_search_voice):
|
|
23
|
+
mock_search_voice.return_value = {"data": [], "next_page_token": None}
|
|
24
|
+
response = self.client.get_data(searchTypes=["asr"], **self.test_params)
|
|
25
|
+
self.assertIsNotNone(response)
|
|
26
|
+
mock_search_voice.assert_called_once_with(**self.test_params)
|
|
27
|
+
|
|
28
|
+
@patch('tvpulse.api.API.search_text')
|
|
29
|
+
def test_get_data_ocr(self, mock_search_text):
|
|
30
|
+
mock_search_text.return_value = {"data": [], "next_page_token": None}
|
|
31
|
+
response = self.client.get_data(searchTypes=["ocr"], **self.test_params)
|
|
32
|
+
self.assertIsNotNone(response)
|
|
33
|
+
mock_search_text.assert_called_once_with(**self.test_params)
|
|
34
|
+
|
|
35
|
+
def test_get_data_no_search_types(self):
|
|
36
|
+
with self.assertRaises(TypeError):
|
|
37
|
+
self.client.get_data(**self.test_params)
|
|
38
|
+
|
|
39
|
+
def test_get_data_empty_search_types(self):
|
|
40
|
+
with self.assertRaises(InvalidRequestError):
|
|
41
|
+
self.client.get_data(searchTypes=[], **self.test_params)
|
|
42
|
+
|
|
43
|
+
def test_get_data_multiple_search_types(self):
|
|
44
|
+
with self.assertRaises(InvalidRequestError):
|
|
45
|
+
self.client.get_data(searchTypes=["asr", "ocr"], **self.test_params)
|
|
46
|
+
|
|
47
|
+
def test_get_data_invalid_search_type(self):
|
|
48
|
+
with self.assertRaises(InvalidRequestError):
|
|
49
|
+
self.client.get_data(searchTypes=["invalid"], **self.test_params)
|
|
50
|
+
|
|
51
|
+
def test_get_data_invalid_stream(self):
|
|
52
|
+
with self.assertRaises(InvalidRequestError):
|
|
53
|
+
params = self.test_params.copy()
|
|
54
|
+
params["streams"] = ["invalid"]
|
|
55
|
+
self.client.get_data(searchTypes=["asr"], **params)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
unittest.main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class API:
|
|
5
|
+
"""
|
|
6
|
+
A wrapper for the TVPulse API.
|
|
7
|
+
"""
|
|
8
|
+
BASE_URL = "https://gateway.dev.sdio.co.jp/v1/api"
|
|
9
|
+
|
|
10
|
+
def __init__(self, api_key: str):
|
|
11
|
+
"""
|
|
12
|
+
Initializes the API client with the given API key.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
api_key: The API key to use for authentication.
|
|
16
|
+
"""
|
|
17
|
+
self.api_key = api_key
|
|
18
|
+
self.headers = {"X-API-KEY": self.api_key}
|
|
19
|
+
|
|
20
|
+
def _request(self, method: str, endpoint: str, **kwargs):
|
|
21
|
+
"""
|
|
22
|
+
Makes a request to the API.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
method: The HTTP method to use (e.g., "GET", "POST").
|
|
26
|
+
endpoint: The API endpoint to call.
|
|
27
|
+
**kwargs: Additional keyword arguments to pass to the request.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The JSON response from the API.
|
|
31
|
+
"""
|
|
32
|
+
url = f"{self.BASE_URL}/{endpoint}"
|
|
33
|
+
response = requests.request(method, url, headers=self.headers, **kwargs)
|
|
34
|
+
print(f"Request URL: {response.url}"
|
|
35
|
+
) # Debugging line to print the request URL
|
|
36
|
+
print(f"Response Status Code: {response.status_code}") # Debugging line to
|
|
37
|
+
if response.status_code == 403:
|
|
38
|
+
from .exceptions import AuthenticationError
|
|
39
|
+
raise AuthenticationError("Invalid API key or insufficient permissions.")
|
|
40
|
+
response.raise_for_status()
|
|
41
|
+
return response.json()
|
|
42
|
+
|
|
43
|
+
def search_text(self, keyword: str, streams: list, start_date: str, end_date: str, frequency: str, score_threshold: float):
|
|
44
|
+
"""
|
|
45
|
+
Performs a text search.
|
|
46
|
+
"""
|
|
47
|
+
payload = {
|
|
48
|
+
"keyword": keyword,
|
|
49
|
+
"streams": streams,
|
|
50
|
+
"start_date": start_date,
|
|
51
|
+
"end_date": end_date,
|
|
52
|
+
"frequency": frequency,
|
|
53
|
+
"score_threshold": score_threshold,
|
|
54
|
+
}
|
|
55
|
+
return self._request("POST", "text/search", json=payload)
|
|
56
|
+
|
|
57
|
+
def search_voice(self, keyword: str, streams: list, start_date: str, end_date: str, frequency: str, score_threshold: float):
|
|
58
|
+
"""
|
|
59
|
+
Performs a voice search.
|
|
60
|
+
"""
|
|
61
|
+
payload = {
|
|
62
|
+
"keyword": keyword,
|
|
63
|
+
"streams": streams,
|
|
64
|
+
"start_date": start_date,
|
|
65
|
+
"end_date": end_date,
|
|
66
|
+
"frequency": frequency,
|
|
67
|
+
"score_threshold": score_threshold,
|
|
68
|
+
}
|
|
69
|
+
return self._request("POST", "voice/search", json=payload)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from .api import API
|
|
2
|
+
from .exceptions import InvalidRequestError
|
|
3
|
+
from .models import APIResponse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Client:
|
|
7
|
+
"""
|
|
8
|
+
The main client for interacting with the TVPulse API.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, api_key: str):
|
|
12
|
+
"""
|
|
13
|
+
Initializes the client with the given API key.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
api_key: The API key to use for authentication.
|
|
17
|
+
"""
|
|
18
|
+
self.api = API(api_key)
|
|
19
|
+
|
|
20
|
+
def get_data(self, searchTypes: list, keyword: str, streams: list,
|
|
21
|
+
start_date: str, end_date: str, frequency: str,
|
|
22
|
+
score_threshold: float):
|
|
23
|
+
"""
|
|
24
|
+
Gets data from the TVPulse API.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
searchTypes: A list of search types to use.
|
|
28
|
+
keyword: The keyword to search for.
|
|
29
|
+
streams: A list of streams to search.
|
|
30
|
+
start_date: The start date of the search.
|
|
31
|
+
end_date: The end date of the search.
|
|
32
|
+
frequency: The frequency of the search.
|
|
33
|
+
score_threshold: The score threshold for the search.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
The JSON response from the API.
|
|
37
|
+
"""
|
|
38
|
+
search_types = searchTypes
|
|
39
|
+
if not isinstance(search_types, list):
|
|
40
|
+
raise InvalidRequestError("searchTypes must be a list.")
|
|
41
|
+
|
|
42
|
+
if not search_types:
|
|
43
|
+
raise InvalidRequestError("searchTypes cannot be empty.")
|
|
44
|
+
|
|
45
|
+
if not isinstance(streams, list):
|
|
46
|
+
raise InvalidRequestError("streams must be a list.")
|
|
47
|
+
|
|
48
|
+
if not streams:
|
|
49
|
+
raise InvalidRequestError("streams cannot be empty.")
|
|
50
|
+
|
|
51
|
+
supported_streams = ["cx", "ex", "mx", "nhk", "ntv", "tbs", "tx"]
|
|
52
|
+
for stream in streams:
|
|
53
|
+
if stream.lower() not in supported_streams:
|
|
54
|
+
raise InvalidRequestError(
|
|
55
|
+
f"Invalid stream: {stream}. Supported streams are: {supported_streams}"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if len(search_types) > 1:
|
|
59
|
+
# For now, we only support one search type at a time.
|
|
60
|
+
# This can be extended to support multiple search types in the future.
|
|
61
|
+
raise InvalidRequestError("Only one search type is supported at a time.")
|
|
62
|
+
|
|
63
|
+
search_type = search_types[0]
|
|
64
|
+
if search_type == "asr":
|
|
65
|
+
response = self.api.search_voice(keyword=keyword,
|
|
66
|
+
streams=streams,
|
|
67
|
+
start_date=start_date,
|
|
68
|
+
end_date=end_date,
|
|
69
|
+
frequency=frequency,
|
|
70
|
+
score_threshold=score_threshold)
|
|
71
|
+
elif search_type == "ocr":
|
|
72
|
+
response = self.api.search_text(keyword=keyword,
|
|
73
|
+
streams=streams,
|
|
74
|
+
start_date=start_date,
|
|
75
|
+
end_date=end_date,
|
|
76
|
+
frequency=frequency,
|
|
77
|
+
score_threshold=score_threshold)
|
|
78
|
+
else:
|
|
79
|
+
raise InvalidRequestError(f"Invalid search type: {search_type}")
|
|
80
|
+
|
|
81
|
+
return APIResponse(**response)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class TVPulseError(Exception):
|
|
2
|
+
"""
|
|
3
|
+
Base class for all TVPulse SDK errors.
|
|
4
|
+
"""
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuthenticationError(TVPulseError):
|
|
9
|
+
"""
|
|
10
|
+
Raised when there is an authentication error.
|
|
11
|
+
"""
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class InvalidRequestError(TVPulseError):
|
|
16
|
+
"""
|
|
17
|
+
Raised when the request is invalid.
|
|
18
|
+
"""
|
|
19
|
+
pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DataPoint(BaseModel):
|
|
6
|
+
"""
|
|
7
|
+
Represents a single data point in the API response.
|
|
8
|
+
"""
|
|
9
|
+
stream: str
|
|
10
|
+
date_time: str
|
|
11
|
+
count: int
|
|
12
|
+
source: Optional[str] = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class APIResponse(BaseModel):
|
|
16
|
+
"""
|
|
17
|
+
Represents the overall API response.
|
|
18
|
+
"""
|
|
19
|
+
data: List[DataPoint]
|
|
20
|
+
next_page_token: Optional[str] = None
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tvpulse
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official TVPulse SDK for Python
|
|
5
|
+
Home-page: https://github.com/sdio/tvpulse-python-sdk
|
|
6
|
+
Author: SDIO
|
|
7
|
+
Author-email: SDIO <dev@sdio.io>
|
|
8
|
+
Project-URL: Homepage, https://github.com/sdio/tvpulse-python-sdk
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/sdio/tvpulse-python-sdk/issues
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.7
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# TVPulse Python SDK
|
|
21
|
+
|
|
22
|
+
The official Python SDK for the TVPulse API.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install tvpulse
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
First, you need to initialize the `Client` with your API key. You can get your API key from the TVPulse UI.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import os
|
|
36
|
+
from tvpulse import Client, TVPulseError
|
|
37
|
+
|
|
38
|
+
# Initialize the SDK
|
|
39
|
+
# It's recommended to store your API key in an environment variable.
|
|
40
|
+
api_key = os.environ.get("TVPULSE_API_KEY")
|
|
41
|
+
if not api_key:
|
|
42
|
+
raise ValueError("TVPULSE_API_KEY environment variable not set.")
|
|
43
|
+
|
|
44
|
+
client = Client(api_key=api_key)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Get Data
|
|
48
|
+
|
|
49
|
+
You can use the `get_data` method to retrieve data from the API. This method takes the following arguments:
|
|
50
|
+
|
|
51
|
+
- `searchTypes`: A list of search types to use. Currently, only one search type is supported at a time. Valid search types are `"asr"` and `"ocr"`.
|
|
52
|
+
- `keyword`: The keyword to search for.
|
|
53
|
+
- `streams`: A list of streams to search.
|
|
54
|
+
- `start_date`: The start date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
55
|
+
- `end_date`: The end date of the search in `YYYY-MM-DD HH:MM:SS` format.
|
|
56
|
+
- `frequency`: The frequency of the search. Valid values are `"hour"` and `"day"`.
|
|
57
|
+
- `score_threshold`: The score threshold for the search. This should be a float between 0 and 1.
|
|
58
|
+
|
|
59
|
+
Here's an example of how to use the `get_data` method:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
try:
|
|
63
|
+
data = client.get_data(
|
|
64
|
+
searchTypes=["asr"],
|
|
65
|
+
keyword="コーヒー",
|
|
66
|
+
streams=["CX", "EX", "NTV", "TBS", "TX"],
|
|
67
|
+
start_date="2025-01-01 00:00:00",
|
|
68
|
+
end_date="2025-01-02 23:59:59",
|
|
69
|
+
frequency="hour",
|
|
70
|
+
score_threshold=0.95
|
|
71
|
+
)
|
|
72
|
+
print(data)
|
|
73
|
+
except TVPulseError as e:
|
|
74
|
+
print(f"An error occurred: {e}")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Error Handling
|
|
78
|
+
|
|
79
|
+
The SDK raises custom exceptions for different types of errors. You can catch these exceptions to handle errors gracefully.
|
|
80
|
+
|
|
81
|
+
- `TVPulseError`: The base class for all SDK errors.
|
|
82
|
+
- `AuthenticationError`: Raised when there is an authentication error (e.g., an invalid API key).
|
|
83
|
+
- `InvalidRequestError`: Raised when the request is invalid (e.g., a missing or invalid parameter).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
tests/test_client.py
|
|
6
|
+
tvpulse/__init__.py
|
|
7
|
+
tvpulse/__version__.py
|
|
8
|
+
tvpulse/api.py
|
|
9
|
+
tvpulse/client.py
|
|
10
|
+
tvpulse/exceptions.py
|
|
11
|
+
tvpulse/models.py
|
|
12
|
+
tvpulse.egg-info/PKG-INFO
|
|
13
|
+
tvpulse.egg-info/SOURCES.txt
|
|
14
|
+
tvpulse.egg-info/dependency_links.txt
|
|
15
|
+
tvpulse.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tvpulse
|