# Search API Python Client v2.0
A comprehensive Python client library for the Search API with enhanced error handling, balance management, and improved data processing. Acquire your API key through @ADSearchEngine_bot on Telegram.
## ๐ New in v2.0
- **Enhanced Balance Management**: Manual balance checking capabilities
- **Access Logs Integration**: Retrieve and analyze API access logs
- **Improved Error Handling**: Comprehensive exception hierarchy with detailed error messages
- **Advanced Caching**: Configurable response caching with TTL
- **Better Data Models**: Enhanced data structures with metadata and cost tracking
- **Context Manager Support**: Automatic resource cleanup
- **Comprehensive Validation**: Input validation for all search types
- **Multiple Phone Formats**: Support for international, national, and E164 formats
- **Batch Operations**: Efficient handling of multiple searches
- **Debug Mode**: Detailed logging for troubleshooting
- **URL Encoding Fix**: Proper handling of phone numbers with + prefix
- **Response Parsing**: Robust handling of both list and dictionary API responses
## ๐ฆ Installation
```bash
pip install AD-SearchAPI
```
## โก Quick Start
```python
from search_api import SearchAPI, InsufficientBalanceError
client = SearchAPI(api_key="your_api_key")
try:
balance = client.get_balance()
print(f"Current balance: {balance}")
print(f"Cost per search: ${balance.credit_cost_per_search}")
access_logs = client.get_access_logs()
print(f"Total access log entries: {len(access_logs)}")
result = client.search_email(
"example@domain.com",
include_house_value=True,
include_extra_info=True
)
print(f"Name: {result.person.name if result.person else 'N/A'}")
print(f"Total results: {result.total_results}")
print(f"Search cost: ${result.search_cost}")
for addr in result.addresses:
print(f"Address: {addr}")
if addr.zestimate:
print(f" Zestimate: ${addr.zestimate:,.2f}")
except InsufficientBalanceError as e:
print(f"Insufficient balance: {e}")
print(f"Current: {e.current_balance}, Required: {e.required_credits}")
```
## ๐ง Advanced Configuration
```python
from search_api import SearchAPI, SearchAPIConfig
config = SearchAPIConfig(
api_key="your_api_key",
debug_mode=True, # Enable debug logging
enable_caching=True, # Enable response caching
cache_ttl=1800, # 30 minutes cache
max_cache_size=500, # Maximum cache entries
timeout=120, # 2 minutes timeout
max_retries=5, # Retry failed requests
proxy={ # Optional proxy
"http": "http://proxy:8080",
"https": "https://proxy:8080"
}
)
client = SearchAPI(config=config)
```
## ๐ฐ Balance Management
The client provides balance checking capabilities, but does not automatically check balance before each search. You should check your balance manually when needed:
```python
from search_api import InsufficientBalanceError
try:
balance = client.get_balance()
print(f"Balance: {balance.current_balance} {balance.currency}")
print(f"Cost per search: {balance.credit_cost_per_search}")
# Calculate required credits based on actual search costs
email_search_cost = 0.0025
phone_search_cost = 0.0025
domain_search_cost = 4.00
required_credits = 5 * email_search_cost
if balance.current_balance < required_credits:
print(f"โ ๏ธ Insufficient balance for {required_credits} searches")
else:
print(f"โ
Sufficient balance for {required_credits} searches")
except InsufficientBalanceError as e:
print(f"โ Insufficient balance: {e}")
print(f" Current: {e.current_balance}")
print(f" Required: {e.required_credits}")
```
## ๐ต Pricing Information
### Search Costs:
- **Email Search**: $0.0025 per search
- **Phone Search**: $0.0025 per search
- **Domain Search**: $4.00 per search
### Optional Parameters:
- **House Value**: Additional $0.0005 per successful lookup
- **Extra Info**: Additional $0.0020 per successful lookup
## ๐ Access Logs
Retrieve and analyze your API access logs:
```python
# Get all access logs
access_logs = client.get_access_logs()
print(f"Total access log entries: {len(access_logs)}")
# Show recent activity
for log in access_logs[:5]:
print(f"IP: {log.ip_address}")
print(f"Last accessed: {log.last_accessed}")
print(f"Endpoint: {log.endpoint}")
print(f"Status: {log.status_code}")
print(f"Response time: {log.response_time:.3f}s")
print("---")
# Analyze access patterns
unique_ips = set(log.ip_address for log in access_logs)
print(f"Unique IP addresses: {len(unique_ips)}")
# Find most active IP
ip_counts = {}
for log in access_logs:
ip_counts[log.ip_address] = ip_counts.get(log.ip_address, 0) + 1
most_active_ip = max(ip_counts.items(), key=lambda x: x[1])
print(f"Most active IP: {most_active_ip[0]} ({most_active_ip[1]} accesses)")
```
## ๐ Search Operations
### Email Search
```python
result = client.search_email(
"john.doe@example.com",
include_house_value=True,
include_extra_info=True,
phone_format="international" # or "national", "e164"
)
print(f"Email: {result.email}")
print(f"Valid: {result.email_valid}")
print(f"Type: {result.email_type}")
print(f"Search Cost: ${result.search_cost}")
if result.person:
print(f"Name: {result.person.name}")
print(f"DOB: {result.person.dob}")
print(f"Age: {result.person.age}")
for addr in result.addresses:
print(f"Address: {addr}")
if addr.zestimate:
print(f" Zestimate: ${addr.zestimate:,.2f}")
for phone in result.phone_numbers:
print(f"Phone: {phone.number}")
```
### Phone Search
```python
results = client.search_phone(
"+1234567890",
include_house_value=True,
include_extra_info=True,
phone_format="international"
)
for result in results:
print(f"Phone: {result.phone.number}")
print(f"Search Cost: ${result.search_cost}")
if result.person:
print(f"Name: {result.person.name}")
print(f"DOB: {result.person.dob}")
print(f"Total results: {result.total_results}")
```
### Domain Search
```python
result = client.search_domain("example.com")
print(f"Domain: {result.domain}")
print(f"Valid: {result.domain_valid}")
print(f"Total results: {result.total_results}")
print(f"Search Cost: ${result.search_cost}")
for email_result in result.results:
print(f"Email: {email_result.email}")
print(f"Valid: {email_result.email_valid}")
print(f"Type: {email_result.email_type}")
if email_result.person:
print(f"Name: {email_result.person.name}")
```
## ๐ก๏ธ Error Handling
The library provides comprehensive error handling with specific exception types:
```python
from search_api import (
SearchAPIError,
AuthenticationError,
ValidationError,
InsufficientBalanceError,
RateLimitError,
ServerError,
NetworkError,
TimeoutError,
ConfigurationError
)
try:
result = client.search_email("test@example.com")
except ValidationError as e:
print(f"Invalid input: {e}")
except InsufficientBalanceError as e:
print(f"Insufficient balance: {e}")
print(f"Current: {e.current_balance}, Required: {e.required_credits}")
except AuthenticationError as e:
print(f"Authentication failed: {e}")
except RateLimitError as e:
print(f"Rate limit exceeded: {e}")
except ServerError as e:
print(f"Server error: {e}")
except NetworkError as e:
print(f"Network error: {e}")
except TimeoutError as e:
print(f"Request timeout: {e}")
except SearchAPIError as e:
print(f"API error: {e}")
```
## ๐ Caching
The client supports configurable response caching:
```python
# Enable caching with custom settings
config = SearchAPIConfig(
api_key="your_api_key",
enable_caching=True,
cache_ttl=3600, # 1 hour
max_cache_size=1000 # Maximum 1000 cached responses
)
client = SearchAPI(config=config)
# Cache is automatically used for repeated searches
result1 = client.search_email("test@example.com") # Cached
result2 = client.search_email("test@example.com") # From cache
# Clear cache when needed
client.clear_cache()
```
## ๐งน Context Manager
Use the client as a context manager for automatic resource cleanup:
```python
with SearchAPI(api_key="your_api_key") as client:
balance = client.get_balance()
result = client.search_email("test@example.com")
# Resources automatically cleaned up when exiting context
```
## ๐ Data Models
### Address Model
```python
@dataclass
class Address:
street: str
city: Optional[str] = None
state: Optional[str] = None
postal_code: Optional[str] = None
country: Optional[str] = None
zestimate: Optional[Decimal] = None
zpid: Optional[str] = None
bedrooms: Optional[int] = None
bathrooms: Optional[float] = None
living_area: Optional[int] = None
home_status: Optional[str] = None
last_known_date: Optional[date] = None
```
### Person Model
```python
@dataclass
class Person:
name: Optional[str] = None
dob: Optional[date] = None
age: Optional[int] = None
```
### PhoneNumber Model
```python
@dataclass
class PhoneNumber:
number: str
country_code: str = "US"
is_valid: bool = True
phone_type: Optional[str] = None
carrier: Optional[str] = None
```
### BalanceInfo Model
```python
@dataclass
class BalanceInfo:
current_balance: float
currency: str = "USD"
last_updated: Optional[datetime] = None
credit_cost_per_search: Optional[float] = None
```
### AccessLog Model
```python
@dataclass
class AccessLog:
ip_address: str
last_accessed: Optional[datetime] = None
user_agent: Optional[str] = None
endpoint: Optional[str] = None
method: Optional[str] = None
status_code: Optional[int] = None
response_time: Optional[float] = None
```
## ๐ง Configuration Options
### SearchAPIConfig
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `api_key` | str | Required | Your API key |
| `base_url` | str | `"https://search-api.dev/search.php"` | API base URL |
| `max_retries` | int | `3` | Maximum retry attempts |
| `timeout` | int | `90` | Request timeout in seconds |
| `debug_mode` | bool | `False` | Enable debug logging |
| `enable_caching` | bool | `True` | Enable response caching |
| `cache_ttl` | int | `3600` | Cache time-to-live in seconds |
| `max_cache_size` | int | `1000` | Maximum cache entries |
| `proxy` | Dict | `None` | Proxy configuration |
| `user_agent` | str | Chrome UA | Custom user agent |
## ๐ Examples
See the `examples/` directory for comprehensive usage examples:
- `basic_usage.py` - Basic search operations, balance checking, and access logs
- `advanced_usage.py` - Advanced features like caching, batch operations, and access log analysis
## ๐ค Contributing
Contributions are welcome! Please submit a Pull Request with your changes or open an issue for discussion.
## ๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/AntiChrist-Coder/search_api_library",
"name": "AD-SearchAPI",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "search-api, email-search, phone-search, domain-search, people-search, api-client, balance-management, caching",
"author": "Search API Team",
"author_email": "support@search-api.dev",
"download_url": "https://files.pythonhosted.org/packages/4b/7b/ed88545aee7025ee1b67fd062f82b93741864163745eda7df84eb5a00b5c/ad_searchapi-2.0.1.tar.gz",
"platform": null,
"description": "# Search API Python Client v2.0\n\nA comprehensive Python client library for the Search API with enhanced error handling, balance management, and improved data processing. Acquire your API key through @ADSearchEngine_bot on Telegram.\n\n## \ud83d\ude80 New in v2.0\n\n- **Enhanced Balance Management**: Manual balance checking capabilities\n- **Access Logs Integration**: Retrieve and analyze API access logs\n- **Improved Error Handling**: Comprehensive exception hierarchy with detailed error messages\n- **Advanced Caching**: Configurable response caching with TTL\n- **Better Data Models**: Enhanced data structures with metadata and cost tracking\n- **Context Manager Support**: Automatic resource cleanup\n- **Comprehensive Validation**: Input validation for all search types\n- **Multiple Phone Formats**: Support for international, national, and E164 formats\n- **Batch Operations**: Efficient handling of multiple searches\n- **Debug Mode**: Detailed logging for troubleshooting\n- **URL Encoding Fix**: Proper handling of phone numbers with + prefix\n- **Response Parsing**: Robust handling of both list and dictionary API responses\n\n## \ud83d\udce6 Installation\n\n```bash\npip install AD-SearchAPI\n```\n\n## \u26a1 Quick Start\n\n```python\nfrom search_api import SearchAPI, InsufficientBalanceError\n\nclient = SearchAPI(api_key=\"your_api_key\")\n\ntry:\n balance = client.get_balance()\n print(f\"Current balance: {balance}\")\n print(f\"Cost per search: ${balance.credit_cost_per_search}\")\n \n access_logs = client.get_access_logs()\n print(f\"Total access log entries: {len(access_logs)}\")\n \n result = client.search_email(\n \"example@domain.com\",\n include_house_value=True,\n include_extra_info=True\n )\n \n print(f\"Name: {result.person.name if result.person else 'N/A'}\")\n print(f\"Total results: {result.total_results}\")\n print(f\"Search cost: ${result.search_cost}\")\n \n for addr in result.addresses:\n print(f\"Address: {addr}\")\n if addr.zestimate:\n print(f\" Zestimate: ${addr.zestimate:,.2f}\")\n \nexcept InsufficientBalanceError as e:\n print(f\"Insufficient balance: {e}\")\n print(f\"Current: {e.current_balance}, Required: {e.required_credits}\")\n```\n\n## \ud83d\udd27 Advanced Configuration\n\n```python\nfrom search_api import SearchAPI, SearchAPIConfig\n\nconfig = SearchAPIConfig(\n api_key=\"your_api_key\",\n debug_mode=True, # Enable debug logging\n enable_caching=True, # Enable response caching\n cache_ttl=1800, # 30 minutes cache\n max_cache_size=500, # Maximum cache entries\n timeout=120, # 2 minutes timeout\n max_retries=5, # Retry failed requests\n proxy={ # Optional proxy\n \"http\": \"http://proxy:8080\",\n \"https\": \"https://proxy:8080\"\n }\n)\n\nclient = SearchAPI(config=config)\n```\n\n## \ud83d\udcb0 Balance Management\n\nThe client provides balance checking capabilities, but does not automatically check balance before each search. You should check your balance manually when needed:\n\n```python\nfrom search_api import InsufficientBalanceError\n\ntry:\n balance = client.get_balance()\n print(f\"Balance: {balance.current_balance} {balance.currency}\")\n print(f\"Cost per search: {balance.credit_cost_per_search}\")\n \n # Calculate required credits based on actual search costs\n email_search_cost = 0.0025\n phone_search_cost = 0.0025\n domain_search_cost = 4.00\n \n required_credits = 5 * email_search_cost\n if balance.current_balance < required_credits:\n print(f\"\u26a0\ufe0f Insufficient balance for {required_credits} searches\")\n else:\n print(f\"\u2705 Sufficient balance for {required_credits} searches\")\n \nexcept InsufficientBalanceError as e:\n print(f\"\u274c Insufficient balance: {e}\")\n print(f\" Current: {e.current_balance}\")\n print(f\" Required: {e.required_credits}\")\n```\n\n## \ud83d\udcb5 Pricing Information\n\n### Search Costs:\n- **Email Search**: $0.0025 per search\n- **Phone Search**: $0.0025 per search \n- **Domain Search**: $4.00 per search\n\n### Optional Parameters:\n- **House Value**: Additional $0.0005 per successful lookup\n- **Extra Info**: Additional $0.0020 per successful lookup\n\n## \ud83d\udcca Access Logs\n\nRetrieve and analyze your API access logs:\n\n```python\n# Get all access logs\naccess_logs = client.get_access_logs()\n\nprint(f\"Total access log entries: {len(access_logs)}\")\n\n# Show recent activity\nfor log in access_logs[:5]:\n print(f\"IP: {log.ip_address}\")\n print(f\"Last accessed: {log.last_accessed}\")\n print(f\"Endpoint: {log.endpoint}\")\n print(f\"Status: {log.status_code}\")\n print(f\"Response time: {log.response_time:.3f}s\")\n print(\"---\")\n\n# Analyze access patterns\nunique_ips = set(log.ip_address for log in access_logs)\nprint(f\"Unique IP addresses: {len(unique_ips)}\")\n\n# Find most active IP\nip_counts = {}\nfor log in access_logs:\n ip_counts[log.ip_address] = ip_counts.get(log.ip_address, 0) + 1\n\nmost_active_ip = max(ip_counts.items(), key=lambda x: x[1])\nprint(f\"Most active IP: {most_active_ip[0]} ({most_active_ip[1]} accesses)\")\n```\n\n## \ud83d\udd0d Search Operations\n\n### Email Search\n\n```python\nresult = client.search_email(\n \"john.doe@example.com\",\n include_house_value=True,\n include_extra_info=True,\n phone_format=\"international\" # or \"national\", \"e164\"\n)\n\nprint(f\"Email: {result.email}\")\nprint(f\"Valid: {result.email_valid}\")\nprint(f\"Type: {result.email_type}\")\nprint(f\"Search Cost: ${result.search_cost}\")\n\nif result.person:\n print(f\"Name: {result.person.name}\")\n print(f\"DOB: {result.person.dob}\")\n print(f\"Age: {result.person.age}\")\n\nfor addr in result.addresses:\n print(f\"Address: {addr}\")\n if addr.zestimate:\n print(f\" Zestimate: ${addr.zestimate:,.2f}\")\n\nfor phone in result.phone_numbers:\n print(f\"Phone: {phone.number}\")\n```\n\n### Phone Search\n\n```python\nresults = client.search_phone(\n \"+1234567890\",\n include_house_value=True,\n include_extra_info=True,\n phone_format=\"international\"\n)\n\nfor result in results:\n print(f\"Phone: {result.phone.number}\")\n print(f\"Search Cost: ${result.search_cost}\")\n \n if result.person:\n print(f\"Name: {result.person.name}\")\n print(f\"DOB: {result.person.dob}\")\n \n print(f\"Total results: {result.total_results}\")\n```\n\n### Domain Search\n\n```python\nresult = client.search_domain(\"example.com\")\n\nprint(f\"Domain: {result.domain}\")\nprint(f\"Valid: {result.domain_valid}\")\nprint(f\"Total results: {result.total_results}\")\nprint(f\"Search Cost: ${result.search_cost}\")\n\nfor email_result in result.results:\n print(f\"Email: {email_result.email}\")\n print(f\"Valid: {email_result.email_valid}\")\n print(f\"Type: {email_result.email_type}\")\n \n if email_result.person:\n print(f\"Name: {email_result.person.name}\")\n```\n\n## \ud83d\udee1\ufe0f Error Handling\n\nThe library provides comprehensive error handling with specific exception types:\n\n```python\nfrom search_api import (\n SearchAPIError,\n AuthenticationError,\n ValidationError,\n InsufficientBalanceError,\n RateLimitError,\n ServerError,\n NetworkError,\n TimeoutError,\n ConfigurationError\n)\n\ntry:\n result = client.search_email(\"test@example.com\")\nexcept ValidationError as e:\n print(f\"Invalid input: {e}\")\nexcept InsufficientBalanceError as e:\n print(f\"Insufficient balance: {e}\")\n print(f\"Current: {e.current_balance}, Required: {e.required_credits}\")\nexcept AuthenticationError as e:\n print(f\"Authentication failed: {e}\")\nexcept RateLimitError as e:\n print(f\"Rate limit exceeded: {e}\")\nexcept ServerError as e:\n print(f\"Server error: {e}\")\nexcept NetworkError as e:\n print(f\"Network error: {e}\")\nexcept TimeoutError as e:\n print(f\"Request timeout: {e}\")\nexcept SearchAPIError as e:\n print(f\"API error: {e}\")\n```\n\n## \ud83d\udd04 Caching\n\nThe client supports configurable response caching:\n\n```python\n# Enable caching with custom settings\nconfig = SearchAPIConfig(\n api_key=\"your_api_key\",\n enable_caching=True,\n cache_ttl=3600, # 1 hour\n max_cache_size=1000 # Maximum 1000 cached responses\n)\n\nclient = SearchAPI(config=config)\n\n# Cache is automatically used for repeated searches\nresult1 = client.search_email(\"test@example.com\") # Cached\nresult2 = client.search_email(\"test@example.com\") # From cache\n\n# Clear cache when needed\nclient.clear_cache()\n```\n\n## \ud83e\uddf9 Context Manager\n\nUse the client as a context manager for automatic resource cleanup:\n\n```python\nwith SearchAPI(api_key=\"your_api_key\") as client:\n balance = client.get_balance()\n result = client.search_email(\"test@example.com\")\n # Resources automatically cleaned up when exiting context\n```\n\n## \ud83d\udcca Data Models\n\n### Address Model\n\n```python\n@dataclass\nclass Address:\n street: str\n city: Optional[str] = None\n state: Optional[str] = None\n postal_code: Optional[str] = None\n country: Optional[str] = None\n zestimate: Optional[Decimal] = None\n zpid: Optional[str] = None\n bedrooms: Optional[int] = None\n bathrooms: Optional[float] = None\n living_area: Optional[int] = None\n home_status: Optional[str] = None\n last_known_date: Optional[date] = None\n```\n\n### Person Model\n\n```python\n@dataclass\nclass Person:\n name: Optional[str] = None\n dob: Optional[date] = None\n age: Optional[int] = None\n```\n\n### PhoneNumber Model\n\n```python\n@dataclass\nclass PhoneNumber:\n number: str\n country_code: str = \"US\"\n is_valid: bool = True\n phone_type: Optional[str] = None\n carrier: Optional[str] = None\n```\n\n### BalanceInfo Model\n\n```python\n@dataclass\nclass BalanceInfo:\n current_balance: float\n currency: str = \"USD\"\n last_updated: Optional[datetime] = None\n credit_cost_per_search: Optional[float] = None\n```\n\n### AccessLog Model\n\n```python\n@dataclass\nclass AccessLog:\n ip_address: str\n last_accessed: Optional[datetime] = None\n user_agent: Optional[str] = None\n endpoint: Optional[str] = None\n method: Optional[str] = None\n status_code: Optional[int] = None\n response_time: Optional[float] = None\n```\n\n## \ud83d\udd27 Configuration Options\n\n### SearchAPIConfig\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `api_key` | str | Required | Your API key |\n| `base_url` | str | `\"https://search-api.dev/search.php\"` | API base URL |\n| `max_retries` | int | `3` | Maximum retry attempts |\n| `timeout` | int | `90` | Request timeout in seconds |\n| `debug_mode` | bool | `False` | Enable debug logging |\n| `enable_caching` | bool | `True` | Enable response caching |\n| `cache_ttl` | int | `3600` | Cache time-to-live in seconds |\n| `max_cache_size` | int | `1000` | Maximum cache entries |\n| `proxy` | Dict | `None` | Proxy configuration |\n| `user_agent` | str | Chrome UA | Custom user agent |\n\n## \ud83d\udcdd Examples\n\nSee the `examples/` directory for comprehensive usage examples:\n\n- `basic_usage.py` - Basic search operations, balance checking, and access logs\n- `advanced_usage.py` - Advanced features like caching, batch operations, and access log analysis\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please submit a Pull Request with your changes or open an issue for discussion.\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n",
"bugtrack_url": null,
"license": null,
"summary": "A comprehensive Python client library for the Search API with enhanced error handling and balance management",
"version": "2.0.1",
"project_urls": {
"Bug Reports": "https://github.com/AntiChrist-Coder/search_api_library/issues",
"Documentation": "https://github.com/AntiChrist-Coder/search_api_library/blob/main/README.md",
"Homepage": "https://github.com/AntiChrist-Coder/search_api_library",
"Source": "https://github.com/AntiChrist-Coder/search_api_library"
},
"split_keywords": [
"search-api",
" email-search",
" phone-search",
" domain-search",
" people-search",
" api-client",
" balance-management",
" caching"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ed9feaafe24b34d08a79616f5e8e9cf2ae4ba5cfbe4fef26cac486727949cfdc",
"md5": "0e8cd13301013a3c8f6e0c757c5ad481",
"sha256": "6a8cf592a2365a2f216ad73c143f1b6682e1bfd63fc88571b71abba66c5dd495"
},
"downloads": -1,
"filename": "ad_searchapi-2.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0e8cd13301013a3c8f6e0c757c5ad481",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 16616,
"upload_time": "2025-08-03T22:51:59",
"upload_time_iso_8601": "2025-08-03T22:51:59.150716Z",
"url": "https://files.pythonhosted.org/packages/ed/9f/eaafe24b34d08a79616f5e8e9cf2ae4ba5cfbe4fef26cac486727949cfdc/ad_searchapi-2.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4b7bed88545aee7025ee1b67fd062f82b93741864163745eda7df84eb5a00b5c",
"md5": "f9696957d4d1dcf6d27b03e7be41cf6b",
"sha256": "ab3b7add2585be757415ce0d949288d99929c9873e54af3b8061044cc8448e3b"
},
"downloads": -1,
"filename": "ad_searchapi-2.0.1.tar.gz",
"has_sig": false,
"md5_digest": "f9696957d4d1dcf6d27b03e7be41cf6b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 18928,
"upload_time": "2025-08-03T22:52:01",
"upload_time_iso_8601": "2025-08-03T22:52:01.342658Z",
"url": "https://files.pythonhosted.org/packages/4b/7b/ed88545aee7025ee1b67fd062f82b93741864163745eda7df84eb5a00b5c/ad_searchapi-2.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-03 22:52:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AntiChrist-Coder",
"github_project": "search_api_library",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": [
[
">=",
"2.31.0"
]
]
},
{
"name": "phonenumbers",
"specs": [
[
">=",
"8.13.0"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
">=",
"2.8.2"
]
]
},
{
"name": "cachetools",
"specs": [
[
">=",
"5.3.0"
]
]
},
{
"name": "typing-extensions",
"specs": [
[
">=",
"4.7.0"
]
]
},
{
"name": "urllib3",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "brotli",
"specs": [
[
">=",
"1.1.0"
]
]
},
{
"name": "pytest",
"specs": [
[
">=",
"7.4.0"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
">=",
"4.1.0"
]
]
},
{
"name": "black",
"specs": [
[
">=",
"23.7.0"
]
]
},
{
"name": "isort",
"specs": [
[
">=",
"5.12.0"
]
]
},
{
"name": "mypy",
"specs": [
[
">=",
"1.5.0"
]
]
},
{
"name": "flake8",
"specs": [
[
">=",
"6.0.0"
]
]
}
],
"lcname": "ad-searchapi"
}