0% found this document useful (0 votes)
7 views3 pages

Book Api Client

The document contains a Python class, BookAPIClient, designed to interact with a book API, allowing users to search for books, retrieve book details, and download PDFs. It includes methods for making HTTP requests with error handling, searching for books by query, and downloading book PDFs. The main function demonstrates the client by searching for books related to 'islam' and attempting to download the PDF of the first result.

Uploaded by

sosohayb75
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views3 pages

Book Api Client

The document contains a Python class, BookAPIClient, designed to interact with a book API, allowing users to search for books, retrieve book details, and download PDFs. It includes methods for making HTTP requests with error handling, searching for books by query, and downloading book PDFs. The main function demonstrates the client by searching for books related to 'islam' and attempting to download the PDF of the first result.

Uploaded by

sosohayb75
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 3

import requests

import json
import os

class BookAPIClient:
def __init__(self, debug=False):
self.base_urls = [
"https://s2.ketabonline.com",
"https://backend.ketabonline.com"
]
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Accept": "application/json, application/pdf",
"Referer": "https://ketabonline.com/",
"Origin": "https://ketabonline.com",
"Api-Lang": "en",
"Platform": "web",
"Accept-Language": "en-US,en;q=0.9",
"API-KEY": "web_da0e7f7f-c0cd-4a80-9f57-268bb9dc8746" # Found in
network requests
}
self.debug = debug

def _make_request(self, url, method="GET", params=None, data=None,


stream=False):
"""Helper method to make HTTP requests with proper error handling"""
try:
if self.debug:
print(f"Making {method} request to: {url}")
if params:
print(f"With params: {params}")
if data:
print(f"With data: {data}")
print(f"Headers: {self.headers}")

response = requests.request(method, url, headers=self.headers,


params=params, json=data, stream=stream)

if self.debug:
print(f"Response status: {response.status_code}")
print(f"Response headers: {response.headers}")
if not stream:
print(f"Response content: {response.text[:500]}...")

if stream and response.status_code == 200:


return response

# Check if response is JSON


try:
response_data = response.json()
except json.JSONDecodeError:
if self.debug:
print(f"Response is not valid JSON: {response.text[:200]}")
return None

if response.status_code == 200:
return response_data
else:
if self.debug:
print(f"Request failed with status {response.status_code}")
return None

except requests.exceptions.RequestException as e:
if self.debug:
print(f"Request error: {str(e)}")
return None

def search_books(self, query, page=1):


"""Search for books"""
for base_url in self.base_urls:
url = f"{base_url}/api/books" # Updated endpoint
params = {
"q": query,
"page": page,
"per_page": 10
}
result = self._make_request(url, params=params)
if result:
return result
return None

def get_book_details(self, book_id):


"""Get details for a specific book"""
for base_url in self.base_urls:
url = f"{base_url}/api/books/{book_id}"
result = self._make_request(url)
if result:
return result
return None

def get_book_pdf(self, book_id):


"""Get PDF preview URL and content for a book"""
for base_url in self.base_urls:
# First try getting book details to find PDF URL
details = self.get_book_details(book_id)

if details and isinstance(details, dict):


# Try various possible PDF URL fields
pdf_url = details.get("pdf_url") or details.get("url") or
details.get("preview_url")
if pdf_url:
if self.debug:
print(f"Found PDF URL in book details: {pdf_url}")
pdf_response = self._make_request(pdf_url, stream=True)
if pdf_response:
return pdf_response

# Try direct PDF endpoints


pdf_endpoints = [
f"{base_url}/api/books/{book_id}/view",
f"{base_url}/api/books/{book_id}/preview",
f"{base_url}/api/books/{book_id}/download",
f"{base_url}/api/books/{book_id}/pdf"
]

for endpoint in pdf_endpoints:


pdf_response = self._make_request(endpoint, stream=True)
if pdf_response:
if self.debug:
print(f"Successfully got PDF from endpoint: {endpoint}")
return pdf_response

return None

def download_book_pdf(self, book_id, output_path=None):


"""Download a book's PDF to a file"""
if output_path is None:
output_path = f"book_{book_id}.pdf"

pdf_response = self.get_book_pdf(book_id)
if not pdf_response:
if self.debug:
print("Failed to get PDF response")
return False

try:
with open(output_path, 'wb') as f:
for chunk in pdf_response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
if self.debug:
print(f"Successfully downloaded PDF to {output_path}")
return True
except Exception as e:
if self.debug:
print(f"Error saving PDF: {str(e)}")
return False

def main():
# Initialize client with debug mode
client = BookAPIClient(debug=True)

# First search for some books to make sure the API is working
print("\nSearching for books...")
search_results = client.search_books("islam")
if search_results:
print(f"Found {len(search_results)} books")
if search_results:
# Try to get the first book's ID
book_id = search_results[0].get('id')
if book_id:
print(f"\nAttempting to download PDF for book {book_id}...")
success = client.download_book_pdf(book_id)
if success:
print(f"PDF successfully downloaded to book_{book_id}.pdf")
else:
print("Failed to download PDF")
else:
print("Could not find book ID in search results")
else:
print("Search failed. API may be down or restricted.")

if __name__ == "__main__":
main()

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy