askpablos-api 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,28 @@
1
+ """
2
+ askpablos_api
3
+
4
+ A Python client library for interacting with the AskPablos proxy API service.
5
+ """
6
+
7
+ from .core import AskPablos
8
+ from .client import ProxyClient
9
+ from .exceptions import (
10
+ AskPablosError,
11
+ AuthenticationError,
12
+ APIConnectionError,
13
+ ResponseError
14
+ )
15
+ from .utils import configure_logging
16
+
17
+ __version__ = "0.1.0"
18
+
19
+ # Set up default exports
20
+ __all__ = [
21
+ "AskPablos",
22
+ "ProxyClient",
23
+ "AskPablosError",
24
+ "AuthenticationError",
25
+ "APIConnectionError",
26
+ "ResponseError",
27
+ "configure_logging",
28
+ ]
@@ -0,0 +1,245 @@
1
+ """
2
+ askpablos_api.client
3
+
4
+ This module provides the main client class for interacting with the AskPablos proxy API.
5
+
6
+ The ProxyClient class handles low-level communication with the AskPablos API service,
7
+ including authentication, request signing, and HTTP communication. It serves as the
8
+ foundation for higher-level interfaces like the AskPablos class.
9
+
10
+ This module is designed for users who need direct control over API requests and
11
+ authentication handling, or for building custom interfaces on top of the base client.
12
+ """
13
+
14
+ import json
15
+ import base64
16
+ import hmac
17
+ import hashlib
18
+ import requests
19
+ from typing import Optional, Dict, Any
20
+
21
+ from .exceptions import APIConnectionError, ResponseError, AuthenticationError
22
+
23
+
24
+ class ResponseData:
25
+ """Response object that provides dot notation access to response data."""
26
+
27
+ def __init__(self, status_code: int, headers: Dict[str, str], content: str,
28
+ url: str, elapsed: float, encoding: Optional[str],
29
+ json_data: Optional[Dict[str, Any]] = None):
30
+ self.status_code = status_code
31
+ self.headers = headers
32
+ self.content = content
33
+ self.url = url
34
+ self.elapsed = elapsed
35
+ self.encoding = encoding
36
+ self.json = json_data
37
+
38
+
39
+ class ProxyClient:
40
+ """
41
+ ProxyClient securely sends requests through the AskPablos proxy service.
42
+
43
+ This is the low-level client that handles direct communication with the AskPablos
44
+ API. It manages authentication via HMAC-SHA256 signatures, constructs proper
45
+ request headers, and handles HTTP communication with the proxy service.
46
+
47
+ The ProxyClient is typically used internally by higher-level classes like AskPablos,
48
+ but can be used directly for fine-grained control over API interactions.
49
+
50
+ Attributes:
51
+ api_key (str): The API key for authentication.
52
+ secret_key (str): The secret key for HMAC signing.
53
+ api_url (str): The base URL of the proxy API service.
54
+
55
+ Security Note:
56
+ This client uses HMAC-SHA256 signatures to ensure request integrity and
57
+ authenticity. The secret_key is never transmitted and is only used locally
58
+ to generate signatures.
59
+ """
60
+
61
+ def __init__(self, api_key: str, secret_key: str, api_url: str):
62
+ """
63
+ Initialize the API client.
64
+
65
+ Sets up the client with authentication credentials and validates that
66
+ all required parameters are provided.
67
+
68
+ Args:
69
+ api_key (str): Your API key from the AskPablos dashboard. This identifies
70
+ your account and is included in the X-API-Key header.
71
+ secret_key (str): Your shared secret for HMAC signing. This is used to
72
+ generate request signatures and must be kept secure.
73
+ api_url (str): The proxy API base URL. This should be the full URL to
74
+ the proxy endpoint.
75
+
76
+ Raises:
77
+ AuthenticationError: If any required credential is missing or empty.
78
+ """
79
+ self.api_key = api_key
80
+ self.secret_key = secret_key
81
+ self.api_url = api_url
82
+
83
+ if not all([api_key, secret_key, api_url]):
84
+ raise AuthenticationError("API key, secret key, and API URL must all be provided")
85
+
86
+ def _generate_signature(self, payload: str) -> str:
87
+ """
88
+ Generate a base64-encoded HMAC SHA256 signature.
89
+
90
+ Creates a cryptographic signature of the request payload using the client's
91
+ secret key. This signature is used by the API server to verify that the
92
+ request came from an authorized client and hasn't been tampered with.
93
+
94
+ Args:
95
+ payload (str): JSON string of the request body that will be signed.
96
+ This should be the exact JSON that will be sent in the
97
+ HTTP request body.
98
+
99
+ Returns:
100
+ str: Base64 encoded HMAC-SHA256 signature of the payload.
101
+
102
+ Note:
103
+ The signature is generated using HMAC-SHA256 with the client's secret key.
104
+ The resulting binary signature is then base64-encoded for transmission
105
+ in HTTP headers.
106
+ """
107
+ signature = hmac.new(
108
+ self.secret_key.encode(),
109
+ payload.encode(),
110
+ hashlib.sha256
111
+ ).digest()
112
+ return base64.b64encode(signature).decode()
113
+
114
+ def _build_headers(self, payload: str) -> dict:
115
+ """
116
+ Construct request headers with API key and signature.
117
+
118
+ Builds the complete set of HTTP headers needed for API authentication,
119
+ including the content type, API key, and request signature.
120
+
121
+ Args:
122
+ payload (str): JSON string of the request body. Used to generate
123
+ the authentication signature.
124
+
125
+ Returns:
126
+ dict: HTTP headers dictionary containing:
127
+ - Content-Type: Set to "application/json"
128
+ - X-API-Key: Your API key for identification
129
+ - X-Signature: HMAC-SHA256 signature of the payload
130
+ """
131
+ return {
132
+ 'Content-Type': 'application/json',
133
+ 'X-API-Key': self.api_key,
134
+ 'X-Signature': self._generate_signature(payload)
135
+ }
136
+
137
+ def request(
138
+ self,
139
+ url: str,
140
+ method: str = "GET",
141
+ data: dict = None,
142
+ headers: dict = None,
143
+ params: dict = None,
144
+ options: dict = None,
145
+ timeout: int = 30
146
+ ) -> ResponseData:
147
+ """
148
+ Send a request through the AskPablos proxy.
149
+
150
+ This is the core method that handles communication with the AskPablos API.
151
+ It constructs the request payload, generates authentication headers,
152
+ and sends the HTTP request to the proxy service.
153
+
154
+ Args:
155
+ url (str): The target URL to fetch through the proxy. Must be a valid
156
+ HTTP or HTTPS URL.
157
+ method (str, optional): HTTP method for the request. Supported methods
158
+ include GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS.
159
+ Defaults to "GET".
160
+ data (dict, optional): Request payload for POST/PUT requests. Will be
161
+ included in the request body sent to the target URL.
162
+ headers (dict, optional): Custom headers to send to the target URL.
163
+ These are forwarded to the target server, not
164
+ used for API authentication.
165
+ params (dict, optional): Query parameters to append to the target URL.
166
+ options (dict, optional): Proxy-specific options controlling how the
167
+ request is processed. See options below.
168
+ timeout (int, optional): Request timeout in seconds. If the proxy
169
+ doesn't respond within this time, the request
170
+ will be cancelled. Defaults to 30.
171
+
172
+ Proxy Options:
173
+ The options dictionary can contain:
174
+ - browser (bool): Use browser automation for JavaScript rendering
175
+ - rotate_proxy (bool): Use proxy rotation for this request
176
+ - user_agent (str): Custom user agent string
177
+ - cookies (dict): Cookies to include with the request
178
+ - Any other proxy-specific options supported by the API
179
+
180
+ Returns:
181
+ dict: The JSON response from the AskPablos API containing the results
182
+ of the proxied request. The exact structure depends on the API
183
+ version, but typically includes status_code, headers, content, etc.
184
+
185
+ Raises:
186
+ APIConnectionError: If the client cannot connect to the AskPablos API
187
+ due to network issues, DNS problems, or timeouts.
188
+ ResponseError: If the API returns an HTTP error status code (4xx or 5xx).
189
+ The exception will include the status code and error message.
190
+ """
191
+ # Initialize options dictionary if not provided
192
+ if options is None:
193
+ options = {}
194
+
195
+ # Create the request data - matching your exact format
196
+ request_data = {
197
+ "url": url,
198
+ "method": method.upper(),
199
+ "browser": options.get("browser", False),
200
+ "rotateProxy": options.get("rotate_proxy", False)
201
+ }
202
+
203
+ if data:
204
+ request_data["data"] = data
205
+
206
+ if headers:
207
+ request_data["headers"] = headers
208
+
209
+ if params:
210
+ request_data["params"] = params
211
+
212
+ # Add any additional options
213
+ for key, value in options.items():
214
+ if key not in ["browser", "rotate_proxy"]:
215
+ request_data[key] = value
216
+
217
+ # Convert to JSON with same separators as your example
218
+ payload = json.dumps(request_data, separators=(',', ':'))
219
+ headers = self._build_headers(payload)
220
+
221
+ try:
222
+ response = requests.post(self.api_url, data=payload, headers=headers, timeout=timeout)
223
+
224
+ if response.status_code >= 400:
225
+ error_msg = response.json().get('error', 'Unknown error') if response.text else 'No error details provided'
226
+ raise ResponseError(response.status_code, error_msg)
227
+
228
+ # Return complete response information
229
+ response_data = ResponseData(
230
+ url=response.url,
231
+ status_code=response.status_code,
232
+ headers=dict(response.headers),
233
+ content=json.loads(response.text).get('data'),
234
+ elapsed=response.elapsed.total_seconds(),
235
+ encoding=response.encoding
236
+ )
237
+
238
+ try:
239
+ response_data.json = response.json()
240
+ except (ValueError, json.JSONDecodeError):
241
+ response_data.json = None
242
+
243
+ return response_data
244
+ except requests.RequestException as e:
245
+ raise APIConnectionError(f"Failed to connect to API: {str(e)}")
@@ -0,0 +1,20 @@
1
+ """
2
+ askpablos_api.config
3
+
4
+ Configuration settings for the AskPablos API client.
5
+
6
+ This module contains default configuration values and settings that can be
7
+ customized if needed. The primary API URL is defined here so users don't
8
+ need to specify it when creating client instances.
9
+ """
10
+
11
+ # Default API configuration
12
+ DEFAULT_API_URL = "http://10.10.10.178:7500/api/proxy/"
13
+
14
+ # Default request settings - matching your example
15
+ DEFAULT_TIMEOUT = 30
16
+ DEFAULT_ROTATE_PROXY = True
17
+ DEFAULT_BROWSER = False
18
+
19
+ # User agent for requests
20
+ DEFAULT_USER_AGENT = "AskPablos-Python-Client/0.1.0"
askpablos_api/core.py ADDED
@@ -0,0 +1,113 @@
1
+ """
2
+ askpablos_api.core
3
+
4
+ Core functionality for the AskPablos proxy API client.
5
+
6
+ This module provides the main AskPablos class, which serves as a simple interface
7
+ for making GET requests through the AskPablos proxy service. The client handles
8
+ authentication, error management, and request formatting automatically.
9
+ """
10
+
11
+ from typing import Dict, Optional
12
+ import logging
13
+
14
+ from .client import ProxyClient, ResponseData
15
+ from .utils import build_proxy_options
16
+ from .exceptions import AskPablosError
17
+ from .config import DEFAULT_API_URL
18
+
19
+ logger = logging.getLogger("askpablos_api")
20
+
21
+
22
+ class AskPablos:
23
+ """
24
+ Simple interface for making GET requests through the AskPablos proxy API.
25
+
26
+ This class provides a clean interface for sending GET requests through the
27
+ AskPablos proxy service. It handles authentication, request formatting,
28
+ and error management automatically.
29
+
30
+ The AskPablos class is designed to be simple and focused - it only supports
31
+ GET requests to keep the interface clean and easy to use.
32
+
33
+ Attributes:
34
+ client (ProxyClient): The underlying client for making API requests.
35
+
36
+ """
37
+
38
+ def __init__(self, api_key: str, secret_key: str):
39
+ """
40
+ Initialize the AskPablos API client.
41
+
42
+ Creates a new instance of the AskPablos client with the provided
43
+ authentication credentials. The client will use these credentials
44
+ for all subsequent API requests.
45
+
46
+ Args:
47
+ api_key (str): Your unique API key from the AskPablos dashboard.
48
+ secret_key (str): Your private secret key used for HMAC signing.
49
+
50
+ Raises:
51
+ AuthenticationError: If any of the required credentials are missing
52
+ or invalid.
53
+ """
54
+ self.client = ProxyClient(api_key, secret_key, DEFAULT_API_URL)
55
+
56
+ def get(
57
+ self,
58
+ url: str,
59
+ params: Optional[Dict[str, str]] = None,
60
+ headers: Optional[Dict[str, str]] = None,
61
+ browser: bool = False,
62
+ rotate_proxy: bool = False,
63
+ timeout: int = 30,
64
+ **options
65
+ ) -> ResponseData:
66
+ """
67
+ Send a GET request through the AskPablos proxy.
68
+
69
+ This is the main method for fetching web pages and API endpoints through
70
+ the AskPablos proxy service. It supports various options for customizing
71
+ the request behavior.
72
+
73
+ Args:
74
+ url (str): The target URL to fetch. Must be a valid HTTP/HTTPS URL.
75
+ params (Dict[str, str], optional): URL query parameters to append.
76
+ Example: {"page": "1", "limit": "10"}
77
+ headers (Dict[str, str], optional): Custom headers for the request.
78
+ browser (bool, optional): Whether to use browser automation for
79
+ JavaScript rendering. Useful for SPAs and
80
+ dynamic content. Defaults to False.
81
+ rotate_proxy (bool, optional): Whether to use proxy rotation for this
82
+ request. Helps avoid rate limiting.
83
+ Defaults to True.
84
+ timeout (int, optional): Request timeout in seconds. Defaults to 30.
85
+ **options: Additional proxy options like user_agent, cookies, etc.
86
+
87
+ Returns:
88
+ ResponseData: The response object from the API containing:
89
+ - status_code (int): HTTP status code from the target server
90
+ - headers (Dict[str, str]): Response headers from target server
91
+ - content (str): Response body/content
92
+ - url (str): Final URL after any redirects
93
+ - elapsed (float): Time taken to complete the request in seconds
94
+ - encoding (Optional[str]): Response text encoding
95
+ - json (Optional[Dict[str, Any]]): Parsed JSON data if available
96
+
97
+ Raises:
98
+ APIConnectionError: If the client cannot connect to the AskPablos API.
99
+ ResponseError: If the API returns an error status code.
100
+ AuthenticationError: If authentication fails.
101
+ """
102
+ # Build proxy options
103
+ proxy_options = build_proxy_options(
104
+ browser=browser,
105
+ rotate_proxy=rotate_proxy,
106
+ **options
107
+ )
108
+
109
+ try:
110
+ return self.client.request(url=url, headers=headers, params=params, options=proxy_options, timeout=timeout)
111
+ except AskPablosError as e:
112
+ logger.error(f"GET request failed: {str(e)}")
113
+ raise
@@ -0,0 +1,79 @@
1
+ """
2
+ askpablos_api.exceptions
3
+
4
+ This module defines exceptions specific to the AskPablos API client.
5
+
6
+ The exception hierarchy is designed to provide clear and specific error handling
7
+ for different types of failures that can occur when interacting with the AskPablos
8
+ API service.
9
+ """
10
+
11
+
12
+ class AskPablosError(Exception):
13
+ """
14
+ Base exception for all AskPablos API errors.
15
+
16
+ This is the root exception class for all errors that can occur within the
17
+ AskPablos API client. All other exceptions inherit from this base class.
18
+ """
19
+ pass
20
+
21
+
22
+ class AuthenticationError(AskPablosError):
23
+ """
24
+ Raised when there is an authentication problem with the API.
25
+
26
+ This exception is raised when:
27
+ - API key is missing or empty
28
+ - Secret key is missing or empty
29
+ - Authentication credentials are invalid
30
+ - HMAC signature verification fails
31
+ """
32
+ pass
33
+
34
+
35
+ class APIConnectionError(AskPablosError):
36
+ """
37
+ Raised when the client fails to connect to the API.
38
+
39
+ This exception is raised when:
40
+ - Network connectivity issues prevent reaching the API
41
+ - DNS resolution fails for the API URL
42
+ - Connection timeouts occur
43
+ - The API server is unreachable or down
44
+ """
45
+ pass
46
+
47
+
48
+ class ResponseError(AskPablosError):
49
+ """
50
+ Raised when there is an error in the API response.
51
+
52
+ This exception is raised when the AskPablos API returns an HTTP error
53
+ status code (4xx or 5xx). It includes both the status code and the
54
+ error message from the API response.
55
+
56
+ Common scenarios:
57
+ - 400 Bad Request: Invalid request parameters
58
+ - 401 Unauthorized: Authentication failed
59
+ - 403 Forbidden: Access denied
60
+ - 404 Not Found: Endpoint not found
61
+ - 429 Too Many Requests: Rate limit exceeded
62
+ - 500 Internal Server Error: Server error
63
+
64
+ Attributes:
65
+ status_code (int): The HTTP status code from the API response
66
+ message (str): The error message from the API response
67
+ """
68
+
69
+ def __init__(self, status_code: int, message: str):
70
+ """
71
+ Initialize a ResponseError with status code and message.
72
+
73
+ Args:
74
+ status_code (int): The HTTP status code from the API response
75
+ message (str): The error message describing what went wrong
76
+ """
77
+ self.status_code = status_code
78
+ self.message = message
79
+ super().__init__(f"API response error (status {status_code}): {message}")
askpablos_api/utils.py ADDED
@@ -0,0 +1,79 @@
1
+ """
2
+ askpablos_api.utils
3
+
4
+ Utility functions and helpers for the AskPablos API client.
5
+
6
+ This module provides utility functions that support the main API client
7
+ functionality, including logging configuration and option building.
8
+ """
9
+
10
+ import logging
11
+ from typing import Optional, Dict, Any
12
+
13
+ # Configure logging
14
+ logger = logging.getLogger("askpablos_api")
15
+
16
+
17
+ def configure_logging(level: int = logging.INFO,
18
+ format_string: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s") -> None:
19
+ """
20
+ Configure the logger for the AskPablos API package.
21
+
22
+ Sets up logging for the AskPablos API client with customizable log level
23
+ and format. This is useful for debugging API requests and understanding
24
+ what's happening during client operations.
25
+
26
+ Args:
27
+ level (int, optional): The logging level to use. Defaults to logging.INFO.
28
+ format_string (str, optional): The format string for log messages.
29
+
30
+ Example:
31
+ >>> from askpablos_api import configure_logging
32
+ >>> import logging
33
+ >>> configure_logging(level=logging.DEBUG)
34
+ """
35
+ handler = logging.StreamHandler()
36
+ formatter = logging.Formatter(format_string)
37
+ handler.setFormatter(formatter)
38
+
39
+ logger.setLevel(level)
40
+ logger.addHandler(handler)
41
+ logger.propagate = False
42
+
43
+
44
+ def build_proxy_options(browser: bool = False,
45
+ rotate_proxy: bool = True,
46
+ user_agent: Optional[str] = None,
47
+ cookies: Optional[Dict[str, str]] = None,
48
+ **kwargs) -> Dict[str, Any]:
49
+ """
50
+ Build a dictionary of options for the proxy request.
51
+
52
+ Creates a standardized options dictionary for proxy requests with common
53
+ parameters and defaults.
54
+
55
+ Args:
56
+ browser (bool, optional): Whether to use browser automation. Defaults to False.
57
+ rotate_proxy (bool, optional): Whether to use proxy rotation. Defaults to True.
58
+ user_agent (str, optional): Custom User-Agent string.
59
+ cookies (Dict[str, str], optional): Dictionary of cookies.
60
+ **kwargs: Additional options to include in the proxy request.
61
+
62
+ Returns:
63
+ Dict[str, Any]: Dictionary of proxy options.
64
+ """
65
+ options = {
66
+ "browser": browser,
67
+ "rotate_proxy": rotate_proxy
68
+ }
69
+
70
+ if user_agent:
71
+ options["user_agent"] = user_agent
72
+
73
+ if cookies:
74
+ options["cookies"] = cookies
75
+
76
+ # Add any additional options
77
+ options.update(kwargs)
78
+
79
+ return options
@@ -0,0 +1,255 @@
1
+ Metadata-Version: 2.4
2
+ Name: askpablos-api
3
+ Version: 0.1.0
4
+ Summary: Professional Python client for the AskPablos proxy API service
5
+ Author-email: Fawad Ali <fawadstar6@gmail.com>
6
+ Maintainer-email: Fawad Ali <fawadstar6@gmail.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/fawadss1/askpablos-api
9
+ Project-URL: Documentation, https://askpablos-api.readthedocs.io
10
+ Project-URL: Repository, https://github.com/fawadss1/askpablos-api
11
+ Project-URL: Bug Tracker, https://github.com/fawadss1/askpablos-api/issues
12
+ Keywords: proxy,api,web-scraping,browser,http-client,askpablos
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Natural Language :: English
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
25
+ Classifier: Topic :: Internet :: Proxy Servers
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: System :: Networking
28
+ Requires-Python: >=3.9
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: requests>=2.25.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=6.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=2.0; extra == "dev"
35
+ Requires-Dist: black>=21.0; extra == "dev"
36
+ Requires-Dist: flake8>=3.8; extra == "dev"
37
+ Requires-Dist: mypy>=0.900; extra == "dev"
38
+ Requires-Dist: pre-commit>=2.0; extra == "dev"
39
+ Provides-Extra: docs
40
+ Requires-Dist: sphinx>=4.0; extra == "docs"
41
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
42
+ Requires-Dist: myst-parser>=0.15; extra == "docs"
43
+ Dynamic: license-file
44
+
45
+ # AskPablos API Client
46
+ [![PyPI Version](https://img.shields.io/pypi/v/askpablos-api.svg)](https://pypi.python.org/pypi/askpablos-api)
47
+ [![Supported Python Versions](https://img.shields.io/pypi/pyversions/askpablos-api.svg)](https://pypi.python.org/pypi/askpablos-api)
48
+
49
+ A simple Python client for making GET requests through the AskPablos proxy API service. This library provides a clean and easy-to-use interface for fetching web pages and APIs through the AskPablos proxy infrastructure.
50
+
51
+ ## Features
52
+
53
+ - 🔐 **Secure Authentication**: HMAC-SHA256 signature-based authentication
54
+ - 🌐 **Proxy Support**: Route requests through rotating proxies
55
+ - 🤖 **Browser Integration**: Support for JavaScript-heavy websites
56
+ - 🛡️ **Error Handling**: Comprehensive exception handling
57
+ - 📊 **Logging**: Built-in logging support for debugging
58
+ - 🎯 **Simple Interface**: GET-only requests for clean API
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ pip install askpablos-api
64
+ ```
65
+
66
+ ## Quick Start
67
+
68
+ ```python
69
+ from askpablos_api import AskPablos
70
+
71
+ # Initialize the client
72
+ client = AskPablos(
73
+ api_key="your_api_key",
74
+ secret_key="your_secret_key"
75
+ )
76
+
77
+ # Make a simple GET request
78
+ response = client.get("https://httpbin.org/ip")
79
+ print(response)
80
+ ```
81
+
82
+ ## Authentication
83
+
84
+ The AskPablos API uses HMAC-SHA256 signature-based authentication. You only need:
85
+
86
+ 1. **API Key**: Your unique API identifier
87
+ 2. **Secret Key**: Your private key for signing requests
88
+
89
+ ```python
90
+ from askpablos_api import AskPablos
91
+
92
+ client = AskPablos(
93
+ api_key="your_api_key",
94
+ secret_key="your_secret_key"
95
+ )
96
+ ```
97
+
98
+ ## Usage Examples
99
+
100
+ ### Basic GET Requests
101
+
102
+ ```python
103
+ # Simple GET request
104
+ response = client.get("https://example.com")
105
+
106
+ # GET with query parameters
107
+ response = client.get(
108
+ "https://api.example.com/users",
109
+ params={"page": 1, "limit": 10}
110
+ )
111
+
112
+ # GET with custom headers
113
+ response = client.get(
114
+ "https://api.example.com/data",
115
+ headers={"Authorization": "Bearer token123"}
116
+ )
117
+ ```
118
+
119
+ ### Advanced Options
120
+
121
+ ```python
122
+ # Use browser automation for JavaScript-heavy sites
123
+ response = client.get(
124
+ "https://spa-website.com",
125
+ browser=True
126
+ )
127
+
128
+ # Disable proxy rotation
129
+ response = client.get(
130
+ "https://example.com",
131
+ rotate_proxy=False
132
+ )
133
+
134
+ # Custom user agent and cookies
135
+ response = client.get(
136
+ "https://example.com",
137
+ user_agent="Mozilla/5.0 (Custom Bot)",
138
+ cookies={"session": "abc123"}
139
+ )
140
+
141
+ # Custom timeout
142
+ response = client.get(
143
+ "https://slow-website.com",
144
+ timeout=60
145
+ )
146
+ ```
147
+
148
+ ### Error Handling
149
+
150
+ ```python
151
+ from askpablos_api import (
152
+ AskPablos,
153
+ AuthenticationError,
154
+ APIConnectionError,
155
+ ResponseError
156
+ )
157
+
158
+ try:
159
+ client = AskPablos(api_key="", secret_key="")
160
+ except AuthenticationError as e:
161
+ print(f"Authentication failed: {e}")
162
+
163
+ try:
164
+ response = client.get("https://example.com")
165
+ except APIConnectionError as e:
166
+ print(f"Connection failed: {e}")
167
+ except ResponseError as e:
168
+ print(f"API error {e.status_code}: {e.message}")
169
+ ```
170
+
171
+ ### Logging
172
+
173
+ ```python
174
+ from askpablos_api import configure_logging
175
+ import logging
176
+
177
+ # Enable debug logging
178
+ configure_logging(level=logging.DEBUG)
179
+
180
+ client = AskPablos(api_key="...", secret_key="...")
181
+ response = client.get("https://example.com") # This will be logged
182
+ ```
183
+
184
+ ## API Reference
185
+
186
+ ### AskPablos Class
187
+
188
+ The main interface for the API client.
189
+
190
+ #### Constructor
191
+
192
+ ```python
193
+ AskPablos(api_key: str, secret_key: str)
194
+ ```
195
+
196
+ **Parameters:**
197
+ - `api_key` (str): Your API key from the AskPablos dashboard
198
+ - `secret_key` (str): Your secret key for HMAC signing
199
+
200
+ #### Methods
201
+
202
+ ##### get()
203
+
204
+ ```python
205
+ get(url, params=None, headers=None, browser=False, rotate_proxy=True, timeout=30, **options)
206
+ ```
207
+
208
+ Send a GET request through the AskPablos proxy.
209
+
210
+ **Parameters:**
211
+ - `url` (str): Target URL to fetch
212
+ - `params` (dict, optional): URL query parameters
213
+ - `headers` (dict, optional): Custom headers
214
+ - `browser` (bool, optional): Use browser automation (default: False)
215
+ - `rotate_proxy` (bool, optional): Enable proxy rotation (default: True)
216
+ - `timeout` (int, optional): Request timeout in seconds (default: 30)
217
+ - `**options`: Additional options like user_agent, cookies, etc.
218
+
219
+ **Returns:** Dictionary containing the API response
220
+
221
+ ### Exception Classes
222
+
223
+ - `AskPablosError` - Base exception class
224
+ - `AuthenticationError` - Authentication-related errors
225
+ - `APIConnectionError` - Connection and network errors
226
+ - `ResponseError` - API response errors
227
+
228
+ ## Response Format
229
+
230
+ All successful requests return a dictionary with:
231
+
232
+ ```python
233
+ {
234
+ "status_code": 200,
235
+ "headers": {"content-type": "text/html", ...},
236
+ "content": "Response body content",
237
+ "url": "Final URL after redirects",
238
+ "proxy_used": "proxy.example.com:8080",
239
+ "time_taken": 1.23
240
+ }
241
+ ```
242
+
243
+ ## Requirements
244
+
245
+ - Python 3.9+
246
+ - requests >= 2.25.0
247
+
248
+ ## License
249
+
250
+ This project is licensed under the MIT License.
251
+
252
+ ## Support
253
+
254
+ For support and questions:
255
+ - Email: fawadstar6@gmail.com
@@ -0,0 +1,11 @@
1
+ askpablos_api/__init__.py,sha256=oFUjsefQY1uzVw_3gXySwfjif1uKozOjz6PU7vLezI0,562
2
+ askpablos_api/client.py,sha256=8WE_mlL5HXxYwddvbY7BS0_FxY7VP6o_NzqABQBsU5A,10296
3
+ askpablos_api/config.py,sha256=k4a9DWqqLqpi6Kj_SaMmugM0lMfdWLLqqakUWJXZ8wI,593
4
+ askpablos_api/core.py,sha256=-flWGRtCIkjoFthnf5k-4tMVJ1qJqo0yXVrgENvXN8M,4692
5
+ askpablos_api/exceptions.py,sha256=FbAlgo8yQ0L6aewT2atnfJVm2ty-8r9WHcx6uCMbrvw,2486
6
+ askpablos_api/utils.py,sha256=0TAzmWutodhSIaHUiCvLlAb6fozDuOhDWZJiQgg-5BI,2584
7
+ askpablos_api-0.1.0.dist-info/licenses/LICENSE,sha256=DhJQ4_j45c_DWghISLKmJshcLvX_Pr7QXaahe2iRMNo,1087
8
+ askpablos_api-0.1.0.dist-info/METADATA,sha256=n9Wm6aINVDWr53vifsNNUJIcl-S32jeTv1GaQoz69Xk,7047
9
+ askpablos_api-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ askpablos_api-0.1.0.dist-info/top_level.txt,sha256=XM61mjwJQtG8sSxvUHD_yMOQKguLv3Yh0hc5S2zHlYc,14
11
+ askpablos_api-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fawad Ali
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 @@
1
+ askpablos_api