tvpulse 0.0.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.0.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.0.0/PKG-INFO ADDED
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: tvpulse
3
+ Version: 0.0.0
4
+ Summary: Official TVPulse SDK for Python
5
+ Author-email: SDIO <dev@sdio.io>
6
+ Project-URL: Homepage, https://github.com/sdio/tvpulse-python-sdk
7
+ Project-URL: Bug Tracker, https://github.com/sdio/tvpulse-python-sdk/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: requests
15
+ Requires-Dist: pydantic
16
+ Dynamic: license-file
17
+
18
+ # TVPulse Python SDK
19
+
20
+ The official Python SDK for the TVPulse API.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install tvpulse
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ First, you need to initialize the `Client` with your API key. You can get your API key from the TVPulse UI.
31
+
32
+ ```python
33
+ import os
34
+ from tvpulse import Client, TVPulseError
35
+
36
+ # Initialize the SDK
37
+ # It's recommended to store your API key in an environment variable.
38
+ api_key = os.environ.get("TVPULSE_API_KEY")
39
+ if not api_key:
40
+ raise ValueError("TVPULSE_API_KEY environment variable not set.")
41
+
42
+ client = Client(api_key=api_key)
43
+ ```
44
+
45
+ ### Get Data
46
+
47
+ You can use the `get_data` method to retrieve data from the API. This method takes the following arguments:
48
+
49
+ - `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"`.
50
+ - `keyword`: The keyword to search for.
51
+ - `streams`: A list of streams to search.
52
+ - `start_date`: The start date of the search in `YYYY-MM-DD HH:MM:SS` format.
53
+ - `end_date`: The end date of the search in `YYYY-MM-DD HH:MM:SS` format.
54
+ - `frequency`: The frequency of the search. Valid values are `"hour"` and `"day"`.
55
+ - `score_threshold`: The score threshold for the search. This should be a float between 0 and 1.
56
+
57
+ Here's an example of how to use the `get_data` method:
58
+
59
+ ```python
60
+ try:
61
+ data = client.get_data(
62
+ searchTypes=["asr"],
63
+ keyword="コーヒー",
64
+ streams=["CX", "EX", "NTV", "TBS", "TX"],
65
+ start_date="2025-01-01 00:00:00",
66
+ end_date="2025-01-02 23:59:59",
67
+ frequency="hour",
68
+ score_threshold=0.95
69
+ )
70
+ print(data)
71
+ except TVPulseError as e:
72
+ print(f"An error occurred: {e}")
73
+ ```
74
+
75
+ ### Error Handling
76
+
77
+ The SDK raises custom exceptions for different types of errors. You can catch these exceptions to handle errors gracefully.
78
+
79
+ - `TVPulseError`: The base class for all SDK errors.
80
+ - `AuthenticationError`: Raised when there is an authentication error (e.g., an invalid API key).
81
+ - `InvalidRequestError`: Raised when the request is invalid (e.g., a missing or invalid parameter).
@@ -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,26 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tvpulse"
7
+ dynamic = ["version"]
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
+ dependencies = [
15
+ "requests",
16
+ "pydantic",
17
+ ]
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ ]
23
+
24
+ [project.urls]
25
+ "Homepage" = "https://github.com/sdio/tvpulse-python-sdk"
26
+ "Bug Tracker" = "https://github.com/sdio/tvpulse-python-sdk/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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,5 @@
1
+ from .client import Client
2
+ from .__version__ import __version__
3
+ from .exceptions import TVPulseError, AuthenticationError, InvalidRequestError
4
+
5
+ __all__ = ["Client", "__version__", "TVPulseError", "AuthenticationError", "InvalidRequestError"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.2"
@@ -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,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: tvpulse
3
+ Version: 0.0.0
4
+ Summary: Official TVPulse SDK for Python
5
+ Author-email: SDIO <dev@sdio.io>
6
+ Project-URL: Homepage, https://github.com/sdio/tvpulse-python-sdk
7
+ Project-URL: Bug Tracker, https://github.com/sdio/tvpulse-python-sdk/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: requests
15
+ Requires-Dist: pydantic
16
+ Dynamic: license-file
17
+
18
+ # TVPulse Python SDK
19
+
20
+ The official Python SDK for the TVPulse API.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install tvpulse
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ First, you need to initialize the `Client` with your API key. You can get your API key from the TVPulse UI.
31
+
32
+ ```python
33
+ import os
34
+ from tvpulse import Client, TVPulseError
35
+
36
+ # Initialize the SDK
37
+ # It's recommended to store your API key in an environment variable.
38
+ api_key = os.environ.get("TVPULSE_API_KEY")
39
+ if not api_key:
40
+ raise ValueError("TVPULSE_API_KEY environment variable not set.")
41
+
42
+ client = Client(api_key=api_key)
43
+ ```
44
+
45
+ ### Get Data
46
+
47
+ You can use the `get_data` method to retrieve data from the API. This method takes the following arguments:
48
+
49
+ - `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"`.
50
+ - `keyword`: The keyword to search for.
51
+ - `streams`: A list of streams to search.
52
+ - `start_date`: The start date of the search in `YYYY-MM-DD HH:MM:SS` format.
53
+ - `end_date`: The end date of the search in `YYYY-MM-DD HH:MM:SS` format.
54
+ - `frequency`: The frequency of the search. Valid values are `"hour"` and `"day"`.
55
+ - `score_threshold`: The score threshold for the search. This should be a float between 0 and 1.
56
+
57
+ Here's an example of how to use the `get_data` method:
58
+
59
+ ```python
60
+ try:
61
+ data = client.get_data(
62
+ searchTypes=["asr"],
63
+ keyword="コーヒー",
64
+ streams=["CX", "EX", "NTV", "TBS", "TX"],
65
+ start_date="2025-01-01 00:00:00",
66
+ end_date="2025-01-02 23:59:59",
67
+ frequency="hour",
68
+ score_threshold=0.95
69
+ )
70
+ print(data)
71
+ except TVPulseError as e:
72
+ print(f"An error occurred: {e}")
73
+ ```
74
+
75
+ ### Error Handling
76
+
77
+ The SDK raises custom exceptions for different types of errors. You can catch these exceptions to handle errors gracefully.
78
+
79
+ - `TVPulseError`: The base class for all SDK errors.
80
+ - `AuthenticationError`: Raised when there is an authentication error (e.g., an invalid API key).
81
+ - `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
+ tests/test_client.py
5
+ tvpulse/__init__.py
6
+ tvpulse/__version__.py
7
+ tvpulse/api.py
8
+ tvpulse/client.py
9
+ tvpulse/exceptions.py
10
+ tvpulse/models.py
11
+ tvpulse.egg-info/PKG-INFO
12
+ tvpulse.egg-info/SOURCES.txt
13
+ tvpulse.egg-info/dependency_links.txt
14
+ tvpulse.egg-info/requires.txt
15
+ tvpulse.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ requests
2
+ pydantic
@@ -0,0 +1 @@
1
+ tvpulse