islamic-content-sdk 1.0.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,3 @@
1
+ from .client import IslamicContentSdk
2
+
3
+ __all__ = ["IslamicContentSdk"]
@@ -0,0 +1,15 @@
1
+ from .services.quranenc import QuranencService
2
+ from .services.hadeethenc import HadeethencService
3
+ from .services.islamhouse import IslamhouseService
4
+ from .services.risalat_al_haramain import RisalatAlHaramainService
5
+ from .services.bayan_al_islam import BayanAlIslamService
6
+ from .services.al_montaka import AlMontakaService
7
+
8
+ class IslamicContentSdk:
9
+ def __init__(self):
10
+ self.quranenc = QuranencService()
11
+ self.hadeethenc = HadeethencService()
12
+ self.islamhouse = IslamhouseService()
13
+ self.risalatAlHaramain = RisalatAlHaramainService()
14
+ self.bayanAlIslam = BayanAlIslamService()
15
+ self.alMontaka = AlMontakaService()
@@ -0,0 +1 @@
1
+ # Services package init
@@ -0,0 +1,129 @@
1
+ from urllib.parse import urlencode
2
+ from .base import BaseService
3
+
4
+ class AlMontakaContentsService(BaseService):
5
+ def __init__(self, baseurl: str):
6
+ super().__init__()
7
+ self.baseurl = baseurl
8
+
9
+ def comments(self, content_id: int):
10
+ url = f"{self.baseurl}/comments?content_id={content_id}"
11
+ return self._request(url)
12
+
13
+ def addComment(self, content_id: int, comment: str):
14
+ url = f"{self.baseurl}/comment"
15
+ body = {
16
+ "content_id": str(content_id),
17
+ "comment": comment
18
+ }
19
+ return self._request(
20
+ url,
21
+ "POST",
22
+ body,
23
+ {"Content-Type": "application/x-www-form-urlencoded"}
24
+ )
25
+
26
+ def content(self, categories: list):
27
+ query_params = {}
28
+ for index, cat in enumerate(categories):
29
+ query_params[f"category[{index}]"] = str(cat)
30
+ query = urlencode(query_params)
31
+ url = f"{self.baseurl}/content?{query}"
32
+ return self._request(url)
33
+
34
+
35
+ class AlMontakaLookupsService(BaseService):
36
+ def __init__(self, baseurl: str):
37
+ super().__init__()
38
+ self.baseurl = baseurl
39
+
40
+ def ageGroups(self):
41
+ url = f"{self.baseurl}/age-groups"
42
+ return self._request(url)
43
+
44
+ def categories(self, params: dict):
45
+ query_params = {
46
+ "language_id": str(params["languageId"]),
47
+ "name_cont": params["nameCont"]
48
+ }
49
+ query = urlencode(query_params)
50
+ url = f"{self.baseurl}/categories?{query}"
51
+ return self._request(url)
52
+
53
+ def entities(self, params: dict):
54
+ query_params = {
55
+ "language_id": str(params["languageId"]),
56
+ "name_cont": params["nameCont"]
57
+ }
58
+ query = urlencode(query_params)
59
+ url = f"{self.baseurl}/entities?{query}"
60
+ return self._request(url)
61
+
62
+ def expertLevels(self, params: dict):
63
+ query_params = {
64
+ "language_id": str(params["languageId"]),
65
+ "name_cont": params["nameCont"]
66
+ }
67
+ query = urlencode(query_params)
68
+ url = f"{self.baseurl}/expert-levels?{query}"
69
+ return self._request(url)
70
+
71
+ def ideologies(self, params: dict):
72
+ query_params = {
73
+ "language_id": str(params["languageId"]),
74
+ "name_cont": params["nameCont"],
75
+ "parent_id": str(params["parentId"])
76
+ }
77
+ query = urlencode(query_params)
78
+ url = f"{self.baseurl}/ideologies?{query}"
79
+ return self._request(url)
80
+
81
+ def languages(self):
82
+ url = f"{self.baseurl}/languages"
83
+ return self._request(url)
84
+
85
+ def persons(self, params=None):
86
+ if params is None:
87
+ params = {}
88
+ query_params = {}
89
+ if params.get("nameCont"):
90
+ query_params["name_cont"] = params["nameCont"]
91
+ if params.get("page") is not None:
92
+ query_params["page"] = params["page"]
93
+
94
+ query = urlencode(query_params)
95
+ url = f"{self.baseurl}/persons?{query}"
96
+ return self._request(url)
97
+
98
+ def sections(self, params: dict):
99
+ query_params = {
100
+ "language_id": str(params["languageId"]),
101
+ "name_cont": params["nameCont"]
102
+ }
103
+ query = urlencode(query_params)
104
+ url = f"{self.baseurl}/sections?{query}"
105
+ return self._request(url)
106
+
107
+ def tags(self, params: dict):
108
+ query_params = {
109
+ "language_id": str(params["languageId"]),
110
+ "name_cont": params["nameCont"]
111
+ }
112
+ query = urlencode(query_params)
113
+ url = f"{self.baseurl}/tags?{query}"
114
+ return self._request(url)
115
+
116
+ def targetedGroups(self):
117
+ url = f"{self.baseurl}/targeted-groups"
118
+ return self._request(url)
119
+
120
+ def youtubeChannels(self):
121
+ url = f"{self.baseurl}/youtube-channels"
122
+ return self._request(url)
123
+
124
+
125
+ class AlMontakaService:
126
+ def __init__(self):
127
+ self.baseurl = "https://content.mofeed.org/Api"
128
+ self.contents = AlMontakaContentsService(self.baseurl)
129
+ self.lookups = AlMontakaLookupsService(self.baseurl)
@@ -0,0 +1,41 @@
1
+ import requests
2
+
3
+ class BaseService:
4
+ def _request(self, url: str, method: str = "GET", body=None, custom_headers=None):
5
+ headers = {
6
+ "Content-Type": "application/json",
7
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
8
+ }
9
+ if custom_headers:
10
+ headers.update(custom_headers)
11
+
12
+ options = {
13
+ "headers": headers
14
+ }
15
+
16
+ if body is not None:
17
+ content_type = headers.get("Content-Type", "")
18
+ if "application/x-www-form-urlencoded" in content_type:
19
+ options["data"] = body
20
+ elif isinstance(body, (dict, list)):
21
+ options["json"] = body
22
+ elif isinstance(body, str):
23
+ options["data"] = body
24
+ else:
25
+ options["data"] = body
26
+
27
+ try:
28
+ response = requests.request(method, url, **options)
29
+ if response.status_code < 200 or response.status_code >= 300:
30
+ raise Exception(f"API request failed with status {response.status_code}: {response.reason}")
31
+
32
+ if not response.text:
33
+ return {}
34
+
35
+ try:
36
+ return response.json()
37
+ except ValueError:
38
+ return response.text
39
+ except Exception as error:
40
+ # Re-throw or format the error professionally
41
+ raise Exception(f"[IslamicContentSdk] {str(error)}")
@@ -0,0 +1,71 @@
1
+ import json
2
+ from urllib.parse import urlencode, quote
3
+ from .base import BaseService
4
+
5
+ class BayanAlIslamService(BaseService):
6
+ def __init__(self):
7
+ super().__init__()
8
+ self.baseurl = "https://byenah.com"
9
+
10
+ def languagesList(self, language: str = "ar"):
11
+ url = f"{self.baseurl}/{language}/Api/languages/list"
12
+ return self._request(url)
13
+
14
+ def muslimList(self, language: str = "en"):
15
+ url = f"{self.baseurl}/{language}/Api/content/muslims/full_list"
16
+ return self._request(url)
17
+
18
+ def nonMuslimList(self, language: str = "en"):
19
+ url = f"{self.baseurl}/{language}/Api/content/non-muslims/full_list"
20
+ return self._request(url)
21
+
22
+ def singleContent(self, content_id: int, language: str = "en"):
23
+ url = f"{self.baseurl}/{language}/Api/single-content?id={content_id}"
24
+ return self._request(url)
25
+
26
+ def paginatedLanguages(self, params=None):
27
+ if params is None:
28
+ params = {}
29
+ language = params.get("language", "en")
30
+ query_params = {}
31
+ if params.get("name"):
32
+ query_params["name"] = params["name"]
33
+ if params.get("page") is not None:
34
+ query_params["page"] = params["page"]
35
+
36
+ query = urlencode(query_params)
37
+ url = f"{self.baseurl}/{language}/Api/paginated-languages?{query}"
38
+ return self._request(url)
39
+
40
+ def recentContents(self, params: dict):
41
+ language = params.get("language", "en")
42
+ query_params = {
43
+ "lang": params["lang"],
44
+ "init": str(params["init"]).lower()
45
+ }
46
+ if params.get("ids") and len(params["ids"]) > 0:
47
+ query_params["ids"] = json.dumps(params["ids"])
48
+
49
+ query = urlencode(query_params)
50
+ url = f"{self.baseurl}/{language}/Api/recent-contents?{query}"
51
+ return self._request(url)
52
+
53
+ def lookups(self, language: str = "en"):
54
+ url = f"{self.baseurl}/{language}/Api/lookups"
55
+ return self._request(url)
56
+
57
+ def nameSearch(self, name: str, language: str = "ar"):
58
+ url = f"{self.baseurl}/{language}/Api/name_search?name={quote(name)}"
59
+ return self._request(url)
60
+
61
+ def availableLanguages(self, content_id: int, language: str = "ar"):
62
+ url = f"{self.baseurl}/{language}/Api/available_languages/{content_id}"
63
+ return self._request(url)
64
+
65
+ def contentTranslation(self, content_id: int, target_language: str, language: str = "en"):
66
+ url = f"{self.baseurl}/{language}/Api/content_translation/{content_id}?language={target_language}"
67
+ return self._request(url)
68
+
69
+ def attachmentsTranslation(self, content_id: int, target_language: str, language: str = "en"):
70
+ url = f"{self.baseurl}/{language}/Api/attachments_translation/{content_id}?language={target_language}"
71
+ return self._request(url)
@@ -0,0 +1,43 @@
1
+ from urllib.parse import urlencode
2
+ from .base import BaseService
3
+
4
+ class HadeethencService(BaseService):
5
+ def __init__(self):
6
+ super().__init__()
7
+ self.baseurl = "https://hadeethenc.com/api/v1"
8
+
9
+ def languages(self):
10
+ url = f"{self.baseurl}/languages"
11
+ return self._request(url)
12
+
13
+ def categories(self, language_code: str):
14
+ query = urlencode({"language": language_code})
15
+ url = f"{self.baseurl}/categories/list/?{query}"
16
+ return self._request(url)
17
+
18
+ def rootCategories(self, language_code: str):
19
+ query = urlencode({"language": language_code})
20
+ url = f"{self.baseurl}/categories/roots/?{query}"
21
+ return self._request(url)
22
+
23
+ def hadithsList(self, params: dict):
24
+ query_params = {"language": params["language"]}
25
+ if params.get("categoryId") is not None:
26
+ query_params["category_id"] = params["categoryId"]
27
+ if params.get("page") is not None:
28
+ query_params["page"] = params["page"]
29
+ if params.get("perPage") is not None:
30
+ query_params["per_page"] = params["perPage"]
31
+
32
+ query = urlencode(query_params)
33
+ url = f"{self.baseurl}/hadeeths/list/?{query}"
34
+ return self._request(url)
35
+
36
+ def hadithDetails(self, params: dict):
37
+ query_params = {
38
+ "id": params["id"],
39
+ "language": params["language"]
40
+ }
41
+ query = urlencode(query_params)
42
+ url = f"{self.baseurl}/hadeeths/one/?{query}"
43
+ return self._request(url)
@@ -0,0 +1,191 @@
1
+ from .base import BaseService
2
+
3
+ class IslamhouseCategoriesAndTypesService(BaseService):
4
+ def __init__(self, baseurl: str):
5
+ super().__init__()
6
+ self.baseurl = baseurl
7
+
8
+ def allTypes(self, site_lang: str, content_lang: str):
9
+ url = f"{self.baseurl}/main/sitecontent/{site_lang}/{content_lang}/json"
10
+ return self._request(url)
11
+
12
+ def allCategories(self, language: str):
13
+ url = f"{self.baseurl}/categories/showall/{language}/json"
14
+ return self._request(url)
15
+
16
+ def categoriesTree(self, language: str):
17
+ url = f"{self.baseurl}/main/get-object-category-tree/{language}/json"
18
+ return self._request(url)
19
+
20
+ def childCategories(self, category_id: int, site_lang: str, content_lang: str):
21
+ url = f"{self.baseurl}/categories/viewcat/{category_id}/{site_lang}/{content_lang}/json"
22
+ return self._request(url)
23
+
24
+ def singleCategoryBasic(self, category_id: int, language: str):
25
+ url = f"{self.baseurl}/categories/viewitem/{category_id}/{language}/json"
26
+ return self._request(url)
27
+
28
+ def subCategories(self, category_id: int, language: str):
29
+ url = f"{self.baseurl}/main/get-sub-categories/{category_id}/{language}/json"
30
+ return self._request(url)
31
+
32
+ def categoryTypes(self, category_id: int, site_lang: str, content_lang: str):
33
+ url = f"{self.baseurl}/main/get-category-types-available/{category_id}/{site_lang}/{content_lang}/json"
34
+ return self._request(url)
35
+
36
+ def categoryLanguages(self, category_id: int, slang: str, language: str):
37
+ url = f"{self.baseurl}/main/get-category-source-languages/{category_id}/{slang}/{language}/json"
38
+ return self._request(url)
39
+
40
+
41
+ class IslamhouseItemsService(BaseService):
42
+ def __init__(self, baseurl: str):
43
+ super().__init__()
44
+ self.baseurl = baseurl
45
+
46
+ def listItems(self, type: str, site_lang: str, slang: str, page: int = 1, limit: int = 25):
47
+ url = f"{self.baseurl}/main/{type}/{site_lang}/{slang}/{page}/{limit}/json"
48
+ return self._request(url)
49
+
50
+ def authorItems(self, author_id: int, slang: str, site_lang: str, content_lang: str, page: int = 1, limit: int = 20):
51
+ url = f"{self.baseurl}/main/get-author-items/{author_id}/{slang}/{site_lang}/{content_lang}/{page}/{limit}/json"
52
+ return self._request(url)
53
+
54
+ def categoryItems(self, category_id: int, slang: str, site_lang: str, content_lang: str, page: int = 1, limit: int = 20):
55
+ url = f"{self.baseurl}/main/get-category-items/{category_id}/{slang}/{site_lang}/{content_lang}/{page}/{limit}/json"
56
+ return self._request(url)
57
+
58
+ def latestItems(self, period: str, slang: str, site_lang: str, content_lang: str, page: int = 1, limit: int = 25):
59
+ url = f"{self.baseurl}/main/get-latest/{period}/{slang}/{site_lang}/{content_lang}/{page}/{limit}/json"
60
+ return self._request(url)
61
+
62
+ def highlightedItems(self, site_lang: str, content_lang: str):
63
+ url = f"{self.baseurl}/main/get-highlights/{site_lang}/{content_lang}/json"
64
+ return self._request(url)
65
+
66
+ def itemsCount(self, type: str, site_lang: str, content_lang: str):
67
+ url = f"{self.baseurl}/main/get-language-items-count/{type}/{site_lang}/{content_lang}/json"
68
+ return self._request(url)
69
+
70
+
71
+ class IslamhouseItemService(BaseService):
72
+ def __init__(self, baseurl: str):
73
+ super().__init__()
74
+ self.baseurl = baseurl
75
+
76
+ def details(self, item_id: int, language: str):
77
+ url = f"{self.baseurl}/main/get-item/{item_id}/{language}/json"
78
+ return self._request(url)
79
+
80
+ def attachments(self, item_id: int):
81
+ url = f"{self.baseurl}/main/check-attachment/{item_id}/json"
82
+ return self._request(url)
83
+
84
+ def tree(self, item_id: int, language: str):
85
+ url = f"{self.baseurl}/main/get-item-tree/{item_id}/{language}/json"
86
+ return self._request(url)
87
+
88
+ def cardTranslations(self, item_id: int, language: str):
89
+ url = f"{self.baseurl}/main/get-item-card-translations/{item_id}/{language}/json"
90
+ return self._request(url)
91
+
92
+ def translations(self, item_id: int, language: str):
93
+ url = f"{self.baseurl}/main/get-item-translations/{item_id}/{language}/json"
94
+ return self._request(url)
95
+
96
+
97
+ class IslamhouseAuthorsService(BaseService):
98
+ def __init__(self, baseurl: str):
99
+ super().__init__()
100
+ self.baseurl = baseurl
101
+
102
+ def list(self, params=None):
103
+ if params is None:
104
+ params = {}
105
+ kind = params.get("kind", "showall")
106
+ locale = params.get("locale", "showall")
107
+ sort = params.get("sort", "countdesc")
108
+ page = params.get("page", 1)
109
+ per_page = params.get("perPage", 20)
110
+
111
+ url = f"{self.baseurl}/main/get-authors-data/{kind}/{locale}/{sort}/{page}/{per_page}/json"
112
+ return self._request(url)
113
+
114
+ def details(self, author_id: int, language: str):
115
+ url = f"{self.baseurl}/main/get-author/{author_id}/{language}/json"
116
+ return self._request(url)
117
+
118
+ def cardTranslations(self, author_id: int, language: str):
119
+ url = f"{self.baseurl}/main/get-author-card-translations/{author_id}/{language}/json"
120
+ return self._request(url)
121
+
122
+ def availableTypes(self, author_id: int, site_lang: str, content_lang: str):
123
+ url = f"{self.baseurl}/main/get-author-types-avaliable/{author_id}/{site_lang}/{content_lang}/json"
124
+ return self._request(url)
125
+
126
+ def availableLocales(self, author_id: int, slang: str, language: str):
127
+ url = f"{self.baseurl}/main/get-author-available-languages/{author_id}/{slang}/{language}/json"
128
+ return self._request(url)
129
+
130
+
131
+ class IslamhouseLanguagesService(BaseService):
132
+ def __init__(self, baseurl: str):
133
+ super().__init__()
134
+ self.baseurl = baseurl
135
+
136
+ def keys(self):
137
+ url = f"{self.baseurl}/languages/get-language-details/json"
138
+ return self._request(url)
139
+
140
+ def terms(self, language: str):
141
+ url = f"{self.baseurl}/languages/get-language-terms/{language}/json"
142
+ return self._request(url)
143
+
144
+ def availableLanguages(self, slang: str, language: str):
145
+ url = f"{self.baseurl}/main/get-available-languages/{slang}/{language}/json"
146
+ return self._request(url)
147
+
148
+
149
+ class IslamhouseQuranService(BaseService):
150
+ def __init__(self, baseurl: str):
151
+ super().__init__()
152
+ self.baseurl = baseurl
153
+
154
+ def categories(self, language: str):
155
+ url = f"{self.baseurl}/quran/get-categories/{language}/json"
156
+ return self._request(url)
157
+
158
+ def singleCategory(self, category_id: int, language: str):
159
+ url = f"{self.baseurl}/quran/get-category/{category_id}/{language}/json"
160
+ return self._request(url)
161
+
162
+ def authorDetails(self, author_id: int, language: str):
163
+ url = f"{self.baseurl}/quran/get-author/{author_id}/{language}/json"
164
+ return self._request(url)
165
+
166
+ def authorRecitations(self, author_id: int, language: str):
167
+ url = f"{self.baseurl}/quran/get-author-recitations/{author_id}/{language}/json"
168
+ return self._request(url)
169
+
170
+ def suraDetails(self, sura_id: int, language: str):
171
+ url = f"{self.baseurl}/quran/get-sura/{sura_id}/{language}/json"
172
+ return self._request(url)
173
+
174
+ def suraRecitations(self, sura_id: int, language: str):
175
+ url = f"{self.baseurl}/quran/get-sura-recitations/{sura_id}/{language}/json"
176
+ return self._request(url)
177
+
178
+ def recitationDetails(self, recitation_id: int, language: str):
179
+ url = f"{self.baseurl}/quran/get-recitation/{recitation_id}/{language}/json"
180
+ return self._request(url)
181
+
182
+
183
+ class IslamhouseService:
184
+ def __init__(self):
185
+ self.baseurl = "https://api3.islamhouse.com/v3/paV29H2gm56kvLPy"
186
+ self.categoriesAndTypes = IslamhouseCategoriesAndTypesService(self.baseurl)
187
+ self.items = IslamhouseItemsService(self.baseurl)
188
+ self.item = IslamhouseItemService(self.baseurl)
189
+ self.authors = IslamhouseAuthorsService(self.baseurl)
190
+ self.languages = IslamhouseLanguagesService(self.baseurl)
191
+ self.quran = IslamhouseQuranService(self.baseurl)
@@ -0,0 +1,41 @@
1
+ from .base import BaseService
2
+
3
+ class QuranencService(BaseService):
4
+ def __init__(self):
5
+ super().__init__()
6
+ self.baseurl = "https://quranenc.com/api/v1"
7
+ self.audio_base_url = "https://d.quranenc.com/data/audio"
8
+
9
+ def translationList(self, params=None):
10
+ if params is None:
11
+ params = {}
12
+
13
+ url = f"{self.baseurl}/translations/list"
14
+ if params.get("language"):
15
+ url += f"/{params['language']}"
16
+ if params.get("localization"):
17
+ url += f"?localization={params['localization']}"
18
+
19
+ return self._request(url)
20
+
21
+ def translationSura(self, translation_key: str, sura_number: int):
22
+ url = f"{self.baseurl}/translation/sura/{translation_key}/{sura_number}"
23
+ return self._request(url)
24
+
25
+ def translationAya(self, translation_key: str, sura_number: int, aya_number: int):
26
+ url = f"{self.baseurl}/translation/aya/{translation_key}/{sura_number}/{aya_number}"
27
+ return self._request(url)
28
+
29
+ def ayaAudio(self, translation_key: str, sura_number: int, aya_number: int):
30
+ sura_3digits = str(sura_number).zfill(3)
31
+ aya_3digits = str(aya_number).zfill(3)
32
+ url = f"{self.audio_base_url}/{translation_key}/{sura_3digits}{aya_3digits}.mp3"
33
+ return {
34
+ "status": 200,
35
+ "file_url": url,
36
+ "content_type": "audio/mpeg"
37
+ }
38
+
39
+ def addNote(self, payload: dict):
40
+ url = f"{self.baseurl}/translations/note"
41
+ return self._request(url, "POST", payload)
@@ -0,0 +1,110 @@
1
+ from urllib.parse import quote
2
+ from .base import BaseService
3
+
4
+ class RisalaContentsService(BaseService):
5
+ def __init__(self, baseurl: str, api_path: str):
6
+ super().__init__()
7
+ self.baseurl = baseurl
8
+ self.api_path = api_path
9
+
10
+ def getFullContents(self, params=None):
11
+ if params is None:
12
+ params = {}
13
+ language = params.get("language", "en")
14
+ lang = params.get("lang", "en")
15
+ url = f"{self.baseurl}/{language}/{self.api_path}/get_full_contents?lang={lang}"
16
+ return self._request(url)
17
+
18
+ def getContents(self, params=None):
19
+ if params is None:
20
+ params = {}
21
+ language = params.get("language", "en")
22
+ lang = params.get("lang", "en")
23
+ url = f"{self.baseurl}/{language}/{self.api_path}/content?lang={lang}"
24
+ return self._request(url)
25
+
26
+ def singleContent(self, content_id: int, language: str = "en"):
27
+ url = f"{self.baseurl}/{language}/{self.api_path}/single-content?id={content_id}"
28
+ return self._request(url)
29
+
30
+ def nameSearch(self, name: str, language: str = "ar"):
31
+ url = f"{self.baseurl}/{language}/{self.api_path}/name_search?name={quote(name)}"
32
+ return self._request(url)
33
+
34
+ def availableLanguages(self, content_id: int, language: str = "ar"):
35
+ url = f"{self.baseurl}/{language}/{self.api_path}/available_languages/{content_id}"
36
+ return self._request(url)
37
+
38
+ def contentTranslation(self, content_id: int, target_language: str, language: str = "en"):
39
+ url = f"{self.baseurl}/{language}/{self.api_path}/content_translation/{content_id}?language={target_language}"
40
+ return self._request(url)
41
+
42
+
43
+ class RisalaIslamicContentService(BaseService):
44
+ def __init__(self, baseurl: str, api_path: str):
45
+ super().__init__()
46
+ self.baseurl = baseurl
47
+ self.api_path = api_path
48
+
49
+ def fatwas(self, params=None):
50
+ if params is None:
51
+ params = {}
52
+ language = params.get("language", "en")
53
+ lang = params.get("lang", "ar")
54
+ is_featured = params.get("isFeatured", 1)
55
+ url = f"{self.baseurl}/{language}/{self.api_path}/fatwas?lang={lang}&is_featured={is_featured}"
56
+ return self._request(url)
57
+
58
+ def hadeeths(self, params=None):
59
+ if params is None:
60
+ params = {}
61
+ language = params.get("language", "en")
62
+ lang = params.get("lang", "ar")
63
+ is_featured = params.get("isFeatured", 1)
64
+ url = f"{self.baseurl}/{language}/{self.api_path}/hadeeths?lang={lang}&is_featured={is_featured}"
65
+ return self._request(url)
66
+
67
+ def quran(self, params=None):
68
+ if params is None:
69
+ params = {}
70
+ language = params.get("language", "en")
71
+ lang = params.get("lang", "ar")
72
+ is_featured = params.get("isFeatured", 1)
73
+ url = f"{self.baseurl}/{language}/{self.api_path}/quran?lang={lang}&is_featured={is_featured}"
74
+ return self._request(url)
75
+
76
+
77
+ class RisalaSearchService(BaseService):
78
+ def __init__(self, baseurl: str, api_path: str):
79
+ super().__init__()
80
+ self.baseurl = baseurl
81
+ self.api_path = api_path
82
+
83
+ def contents(self, query: str, language: str = "en"):
84
+ url = f"{self.baseurl}/{language}/{self.api_path}/search?query={quote(query)}"
85
+ return self._request(url)
86
+
87
+
88
+ class RisalaLookupsService(BaseService):
89
+ def __init__(self, baseurl: str, api_path: str):
90
+ super().__init__()
91
+ self.baseurl = baseurl
92
+ self.api_path = api_path
93
+
94
+ def languages(self, language: str = "en", api_key: str = "A7X9G2L5M8P4T1C3D6V0KJQZRYBWFNSHEUO9682XLMTGVDPKJHQC7R5ZYA1B3W4F"):
95
+ url = f"{self.baseurl}/{language}/{self.api_path}/langs?api_key={api_key}"
96
+ return self._request(url)
97
+
98
+ def contentTypes(self, language: str = "en"):
99
+ url = f"{self.baseurl}/{language}/{self.api_path}/content-types"
100
+ return self._request(url)
101
+
102
+
103
+ class RisalatAlHaramainService:
104
+ def __init__(self):
105
+ self.baseurl = "https://risala.prh.gov.sa"
106
+ self.api_path = "Api"
107
+ self.contents = RisalaContentsService(self.baseurl, self.api_path)
108
+ self.islamicContent = RisalaIslamicContentService(self.baseurl, self.api_path)
109
+ self.search = RisalaSearchService(self.baseurl, self.api_path)
110
+ self.lookups = RisalaLookupsService(self.baseurl, self.api_path)
@@ -0,0 +1,483 @@
1
+ Metadata-Version: 2.1
2
+ Name: islamic-content-sdk
3
+ Version: 1.0.0
4
+ Summary: An integrated and easy-to-use software library to fetch authentic Islamic content (Holy Quran and Hadith) in multiple languages.
5
+ Home-page: https://github.com/2yousefreda/islamic-content-sdk-npm
6
+ Author: The Association for Multi-lingual Islamic Content
7
+ Author-email: info@islamiccontent.sa
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: ISC License (ISCL)
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests >=2.25.0
14
+
15
+ # Islamic Content SDK (Python)
16
+
17
+ An integrated and easy-to-use software library for Python developers to fetch authentic Islamic content (The Holy Qur'an and Hadith) in multiple languages directly from official sources.
18
+
19
+ This project is developed for [The Association for Multi-lingual Islamic Content](https://islamiccontent.sa/).
20
+
21
+ ---
22
+
23
+ ## Services Overview
24
+
25
+ This SDK aggregates content from multiple major multi-lingual Islamic platforms:
26
+
27
+ - **QuranEnc (`quranenc`)**: Quran Translations, suras, verses, and audios.
28
+ - **HadeethEnc (`hadeethenc`)**: Hadith collections, category trees, and grades.
29
+ - **IslamHouse (`islamhouse`)**: Multi-lingual books, articles, audios, fatwas, and author details.
30
+ - **Risalat Al-Haramain (`risalatAlHaramain`)**: Platform content, Fatwas, Quran recitations, and Hadiths.
31
+ - **Bayan Al Islam (`bayanAlIslam`)**: Educational booklets and resources tailored for Muslims and Non-Muslims.
32
+ - **Al Montaka (`alMontaka`)**: Structured lookups, categories, content filters, and community comments.
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ Install the package via pip:
39
+
40
+ ```bash
41
+ pip install islamic-content-sdk
42
+ ```
43
+
44
+ ## Usage
45
+
46
+ ### Initializing the SDK
47
+
48
+ ```python
49
+ from islamic_content_sdk import IslamicContentSdk
50
+
51
+ sdk = IslamicContentSdk()
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Detailed Service Methods Reference
57
+
58
+ Below is a complete guide on how to interact with every single method and option available in the SDK.
59
+
60
+ ### Quran Source (QuranEnc API)
61
+
62
+ **API Documentation Link:** [QuranEnc API](https://quranenc.com/en/home/api/)
63
+
64
+ ```python
65
+ # 1. Get available translations list on the platform
66
+ translations = sdk.quranenc.translationList({
67
+ "language": "es", # Optional: Filter list by language code
68
+ "localization": "ar" # Optional: Localize names in the response
69
+ })
70
+
71
+ # 2. Translate an entire sura (Al-Fatiha in Spanish)
72
+ sura = sdk.quranenc.translationSura("spanish_montada_eu", 1)
73
+
74
+ # 3. Translate a specific verse (Ayah 1 of Sura 1)
75
+ aya = sdk.quranenc.translationAya("spanish_montada_eu", 1, 1)
76
+
77
+ # 4. Get the audio MP3 file details for a specific verse
78
+ audio = sdk.quranenc.ayaAudio("chinese_suliman", 1, 1)
79
+ # Returns: {"status": 200, "file_url": "...", "content_type": "audio/mpeg"}
80
+
81
+ # 5. Submit translation feedback/note (POST request)
82
+ note_response = sdk.quranenc.addNote({
83
+ "sura": 1,
84
+ "aya": 1,
85
+ "name": "QA Tester",
86
+ "email": "qa@example.com",
87
+ "note": "Test note from SDK automated test suite",
88
+ "translation_key": "spanish_montada_eu",
89
+ "source": "sdk_test",
90
+ "version": "1.0.0",
91
+ "suggested_translation": "Suggested text" # Optional
92
+ })
93
+ ```
94
+
95
+ ---
96
+
97
+ ### Hadith Source (HadeethEnc API)
98
+
99
+ **API Documentation Link:** [HadeethEnc API](https://documenter.getpostman.com/view/5211979/TVev3j7q#intro)
100
+
101
+ ```python
102
+ # 1. Get available languages in the encyclopedia
103
+ languages = sdk.hadeethenc.languages()
104
+
105
+ # 2. Get all categories of Hadith translated in a specific language
106
+ categories = sdk.hadeethenc.categories("en")
107
+
108
+ # 3. Get main (root) categories of Hadith in English
109
+ root_categories = sdk.hadeethenc.rootCategories("en")
110
+
111
+ # 4. List Hadiths under a category with pagination
112
+ hadiths = sdk.hadeethenc.hadithsList({
113
+ "language": "en",
114
+ "categoryId": 1, # Optional: Category ID
115
+ "page": 1, # Optional: Page number
116
+ "perPage": 20 # Optional: Number of items per page
117
+ })
118
+
119
+ # 5. Get full explanation, translations, and grade of a specific Hadith by ID
120
+ hadith = sdk.hadeethenc.hadithDetails({
121
+ "id": 2962,
122
+ "language": "ar"
123
+ })
124
+ ```
125
+
126
+ ---
127
+
128
+ ### IslamHouse Source (IslamHouse v3 API)
129
+
130
+ **API Documentation Link:** [IslamHouse API Docs](https://documenter.getpostman.com/view/7929737/TzkyMfPc)
131
+
132
+ ```python
133
+ # ==========================================
134
+ # 1. Categories & Types (categoriesAndTypes)
135
+ # ==========================================
136
+
137
+ # Core material types (videos, books, fatwas, etc.)
138
+ types = sdk.islamhouse.categoriesAndTypes.allTypes("ar", "ar") # siteLang, contentLang
139
+
140
+ # Get all categories in the database
141
+ all_categories = sdk.islamhouse.categoriesAndTypes.allCategories("ar")
142
+
143
+ # Complete category hierarchy tree
144
+ tree = sdk.islamhouse.categoriesAndTypes.categoriesTree("ar")
145
+
146
+ # Subcategories of a category with content lang localization
147
+ child_cats = sdk.islamhouse.categoriesAndTypes.childCategories(1, "ar", "ar") # categoryId, siteLang, contentLang
148
+
149
+ # Basic details of a category by ID
150
+ single_category = sdk.islamhouse.categoriesAndTypes.singleCategoryBasic(1, "ar")
151
+
152
+ # Subcategories with nested children
153
+ sub_categories = sdk.islamhouse.categoriesAndTypes.subCategories(1, "ar")
154
+
155
+ # Available material types under a specific category ID
156
+ category_types = sdk.islamhouse.categoriesAndTypes.categoryTypes(1, "ar", "ar")
157
+
158
+ # Available languages for materials within a category ID
159
+ category_langs = sdk.islamhouse.categoriesAndTypes.categoryLanguages(1, "ar", "ar") # id, slang, language
160
+
161
+ # ==========================================
162
+ # 2. Items Listings (items)
163
+ # ==========================================
164
+
165
+ # List materials by type (e.g. "books", "videos", "audios") and language
166
+ items = sdk.islamhouse.items.listItems("books", "ar", "ar", 1, 25) # type, siteLang, slang, page, limit
167
+
168
+ # List materials published by a specific author ID
169
+ author_items = sdk.islamhouse.items.authorItems(1, "ar", "ar", "ar", 1, 20) # authorId, slang, siteLang, contentLang, page, limit
170
+
171
+ # List materials categorized under a category ID
172
+ cat_items = sdk.islamhouse.items.categoryItems(1, "ar", "ar", "ar", 1, 20) # categoryId, slang, siteLang, contentLang, page, limit
173
+
174
+ # List latest items by period (e.g., "week", "month")
175
+ latest_items = sdk.islamhouse.items.latestItems("week", "ar", "ar", "ar", 1, 25) # period, slang, siteLang, contentLang, page, limit
176
+
177
+ # Highlighted featured items on the homepage
178
+ highlights = sdk.islamhouse.items.highlightedItems("ar", "ar") # siteLang, contentLang
179
+
180
+ # Get the total count of items available for a specific type
181
+ items_count = sdk.islamhouse.items.itemsCount("books", "ar", "ar") # type, siteLang, contentLang
182
+
183
+ # ==========================================
184
+ # 3. Single Item Details (item)
185
+ # ==========================================
186
+
187
+ # Details, metadata, and description of a single item
188
+ item_details = sdk.islamhouse.item.details(228065, "ar")
189
+
190
+ # List downloadable media/PDF attachments for an item
191
+ attachments = sdk.islamhouse.item.attachments(228065)
192
+
193
+ # Category tree path leading to this item
194
+ item_tree = sdk.islamhouse.item.tree(228065, "ar")
195
+
196
+ # Translation card details of the item
197
+ item_card_trans = sdk.islamhouse.item.cardTranslations(228065, "ar")
198
+
199
+ # Other translation languages available for this item
200
+ translations = sdk.islamhouse.item.translations(228065, "ar")
201
+
202
+ # ==========================================
203
+ # 4. Authors and Publishers (authors)
204
+ # ==========================================
205
+
206
+ # List authors/sources with filter and sort parameters
207
+ authors = sdk.islamhouse.authors.list({
208
+ "kind": "author", # Optional: "showall" | "author" | "source"
209
+ "locale": "ar", # Optional: "showall" | language code
210
+ "sort": "countdesc", # Optional
211
+ "page": 1, # Optional
212
+ "perPage": 10 # Optional
213
+ })
214
+
215
+ # Specific author details by ID
216
+ author_details = sdk.islamhouse.authors.details(1, "ar")
217
+
218
+ # Translation card details of an author
219
+ author_card = sdk.islamhouse.authors.cardTranslations(1, "ar")
220
+
221
+ # Material types available for an author
222
+ author_types = sdk.islamhouse.authors.availableTypes(1, "ar", "ar")
223
+
224
+ # Languages available for an author
225
+ author_langs = sdk.islamhouse.authors.availableLocales(1, "ar", "ar")
226
+
227
+ # ==========================================
228
+ # 5. Languages & Terms (languages)
229
+ # ==========================================
230
+
231
+ # Details of all supported languages on the platform
232
+ lang_keys = sdk.islamhouse.languages.keys()
233
+
234
+ # Interface translation terms for localization
235
+ terms = sdk.islamhouse.languages.terms("ar")
236
+
237
+ # Available languages relative to another
238
+ avail_langs = sdk.islamhouse.languages.availableLanguages("ar", "ar")
239
+
240
+ # ==========================================
241
+ # 6. Holy Quran Recitations (quran)
242
+ # ==========================================
243
+
244
+ # Quran recitation categories (reciters, sections)
245
+ quran_categories = sdk.islamhouse.quran.categories("ar")
246
+
247
+ # Basic details of a Quran category
248
+ quran_category = sdk.islamhouse.quran.singleCategory(1, "ar")
249
+
250
+ # Details about a specific reciter
251
+ reciter_details = sdk.islamhouse.quran.authorDetails(1, "ar")
252
+
253
+ # Recitations list of a specific reciter
254
+ recitations = sdk.islamhouse.quran.authorRecitations(1, "ar")
255
+
256
+ # Detailed info of a specific Quran Surah
257
+ sura_details = sdk.islamhouse.quran.suraDetails(1, "ar")
258
+
259
+ # Audio recordings of a specific Surah by various reciters
260
+ sura_recitations = sdk.islamhouse.quran.suraRecitations(1, "ar")
261
+
262
+ # Details of a specific Quran recitation by ID
263
+ recitation = sdk.islamhouse.quran.recitationDetails(228065, "ar")
264
+ ```
265
+
266
+ ---
267
+
268
+ ### Risalat Al-Haramain Source (Risalat Al-Haramain API)
269
+
270
+ **API Documentation Link:** [Risalat Al-Haramain API](https://risala.prh.gov.sa/en/Api/content)
271
+
272
+ ```python
273
+ # ==========================================
274
+ # 1. Platform Contents (contents)
275
+ # ==========================================
276
+
277
+ # Get full content of the platform in a specific language
278
+ full_contents = sdk.risalatAlHaramain.contents.getFullContents({
279
+ "language": "en", # Optional: URL language path (default: "en")
280
+ "lang": "en" # Optional: Query parameter language (default: "en")
281
+ })
282
+
283
+ # Retrieve contents with optional parameters
284
+ contents = sdk.risalatAlHaramain.contents.getContents({
285
+ "language": "en",
286
+ "lang": "en"
287
+ })
288
+
289
+ # Get detailed content of a single item
290
+ single_content = sdk.risalatAlHaramain.contents.singleContent(1, "en")
291
+
292
+ # Quick search items by name
293
+ name_search_result = sdk.risalatAlHaramain.contents.nameSearch("حصن", "ar")
294
+
295
+ # Check available translation languages for an item
296
+ risala_avail_langs = sdk.risalatAlHaramain.contents.availableLanguages(1, "ar")
297
+
298
+ # Get translation of a content item into a target language
299
+ content_translation = sdk.risalatAlHaramain.contents.contentTranslation(1, "en", "ar") # id, targetLanguage, language
300
+
301
+ # ==========================================
302
+ # 2. Islamic Content Modules (islamicContent)
303
+ # ==========================================
304
+
305
+ # Get Fatwas
306
+ fatwas = sdk.risalatAlHaramain.islamicContent.fatwas({
307
+ "language": "en", # Optional
308
+ "lang": "ar", # Optional
309
+ "isFeatured": 1 # Optional: 0 or 1
310
+ })
311
+
312
+ # Get featured Hadiths
313
+ hadeeths = sdk.risalatAlHaramain.islamicContent.hadeeths({
314
+ "language": "en",
315
+ "lang": "ar",
316
+ "isFeatured": 1
317
+ })
318
+
319
+ # Get featured Quran recitations
320
+ quran_content = sdk.risalatAlHaramain.islamicContent.quran({
321
+ "language": "en",
322
+ "lang": "ar",
323
+ "isFeatured": 1
324
+ })
325
+
326
+ # ==========================================
327
+ # 3. Platform Search (search)
328
+ # ==========================================
329
+
330
+ # Keyword text search across platform content
331
+ search_result = sdk.risalatAlHaramain.search.contents("حصن", "en")
332
+
333
+ # ==========================================
334
+ # 4. Lookups & Meta (lookups)
335
+ # ==========================================
336
+
337
+ # Get available languages
338
+ risala_langs = sdk.risalatAlHaramain.lookups.languages("en")
339
+
340
+ # Get available content types
341
+ content_types = sdk.risalatAlHaramain.lookups.contentTypes("en")
342
+ ```
343
+
344
+ ---
345
+
346
+ ### Bayan Al Islam Source (Bayan Al Islam API)
347
+
348
+ **Postman Resources:** [Collection](https://byenah.com/download-request?name=Bayan%20Al%20Islam.postman_collection.json) | [Environment](https://byenah.com/download-request?name=Bayan%20al%20islam%20env.postman_environment.json)
349
+
350
+ ```python
351
+ # 1. Get list of available languages
352
+ bayan_langs = sdk.bayanAlIslam.languagesList("ar")
353
+
354
+ # 2. Get content list tailored for Muslims
355
+ muslim_list = sdk.bayanAlIslam.muslimList("en")
356
+
357
+ # 3. Get content list tailored for Non-Muslims
358
+ non_muslim_list = sdk.bayanAlIslam.nonMuslimList("en")
359
+
360
+ # 4. Get details of a specific content item by ID
361
+ content_details = sdk.bayanAlIslam.singleContent(22184, "en")
362
+
363
+ # 5. Get languages list paginated and filtered by name
364
+ paginated_langs = sdk.bayanAlIslam.paginatedLanguages({
365
+ "name": "English", # Optional
366
+ "page": 1, # Optional
367
+ "language": "en" # Optional
368
+ })
369
+
370
+ # 6. Get recent contents (Muslim/Non-Muslim updates)
371
+ recent = sdk.bayanAlIslam.recentContents({
372
+ "lang": "ar",
373
+ "init": True,
374
+ "ids": [22184], # Optional: content IDs list
375
+ "language": "en" # Optional
376
+ })
377
+
378
+ # 7. Get website lookup variables
379
+ lookups = sdk.bayanAlIslam.lookups("en")
380
+
381
+ # 8. Search materials by title/name
382
+ search_result = sdk.bayanAlIslam.nameSearch("حصن", "ar")
383
+
384
+ # 9. Check available translation languages for a content ID
385
+ avail_langs = sdk.bayanAlIslam.availableLanguages(22184, "ar")
386
+
387
+ # 10. Get specific translation of a content item
388
+ translation = sdk.bayanAlIslam.contentTranslation(22184, "en", "ar") # id, targetLanguage, language
389
+
390
+ # 11. Get translations for media or PDF attachments of a content item
391
+ attachments_trans = sdk.bayanAlIslam.attachmentsTranslation(22184, "en", "ar") # id, targetLanguage, language
392
+ ```
393
+
394
+ ---
395
+
396
+ ### Al Montaka Source (Al Montaka API)
397
+
398
+ **API Documentation Link:** [Al Montaka API](https://documenter.getpostman.com/view/5211979/2s8YzMZ6Fu)
399
+
400
+ ```python
401
+ # ==========================================
402
+ # 1. Content and Comments (contents)
403
+ # ==========================================
404
+
405
+ # Get all comments for a specific content ID
406
+ comments = sdk.alMontaka.contents.comments(1)
407
+
408
+ # Add a new comment to a specific content item
409
+ new_comment = sdk.alMontaka.contents.addComment(1, "Test comment")
410
+
411
+ # Get filtered content by category IDs
412
+ filtered_content = sdk.alMontaka.contents.content([1, 2])
413
+
414
+ # ==========================================
415
+ # 2. Site Lookups and Filters (lookups)
416
+ # ==========================================
417
+
418
+ # Get target age groups
419
+ age_groups = sdk.alMontaka.lookups.ageGroups()
420
+
421
+ # Get categories matching language and name filter
422
+ categories = sdk.alMontaka.lookups.categories({
423
+ "languageId": 1,
424
+ "nameCont": "General"
425
+ })
426
+
427
+ # Get publishing entities matching language and name filter
428
+ entities = sdk.alMontaka.lookups.entities({
429
+ "languageId": 1,
430
+ "nameCont": "Dar"
431
+ })
432
+
433
+ # Get expertise/scientific levels matching filter
434
+ expert_levels = sdk.alMontaka.lookups.expertLevels({
435
+ "languageId": 1,
436
+ "nameCont": "Level"
437
+ })
438
+
439
+ # Get ideologies matching filter
440
+ ideologies = sdk.alMontaka.lookups.ideologies({
441
+ "languageId": 1,
442
+ "nameCont": "Sunnah",
443
+ "parentId": 0
444
+ })
445
+
446
+ # Get available languages
447
+ languages = sdk.alMontaka.lookups.languages()
448
+
449
+ # Get/search scholars, narrators, or personalities
450
+ persons = sdk.alMontaka.lookups.persons({
451
+ "nameCont": "Muhammad", # Optional
452
+ "page": 1 # Optional
453
+ })
454
+
455
+ # Get website sections matching filter
456
+ sections = sdk.alMontaka.lookups.sections({
457
+ "languageId": 1,
458
+ "nameCont": "Section"
459
+ })
460
+
461
+ # Get tags matching filter
462
+ tags = sdk.alMontaka.lookups.tags({
463
+ "languageId": 1,
464
+ "nameCont": "Tag"
465
+ })
466
+
467
+ # Get targeted groups of audience
468
+ targeted_groups = sdk.alMontaka.lookups.targetedGroups()
469
+
470
+ # Get integrated YouTube channels list
471
+ youtube_channels = sdk.alMontaka.lookups.youtubeChannels()
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Donation & Support
477
+
478
+ You can support the projects and efforts of The Association for Multi-lingual Islamic Content through the following official channels:
479
+
480
+ - [Support Projects (Wakfy)](https://islamiccontent.org/Wakfy)
481
+ - [Bank Accounts](https://islamiccontent.org/Accounts)
482
+ - [Association Store](https://store.islamiccontent.sa/)
483
+ - [Annual Operational Support (الدعم التشغيلي السنوي للجمعية)](https://store.islamiccontent.sa/%D8%A7%D9%84%D9%85%D8%B5%D8%B1%D9%88%D9%81%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B4%D8%BA%D9%8A%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%B3%D9%86%D9%88%D9%8A%D8%A9-%D9%84%D9%84%D8%AC%D9%85%D8%B9%D9%8A-%D8%A9/p1950956689)
@@ -0,0 +1,14 @@
1
+ islamic_content_sdk/__init__.py,sha256=kIJsZXF4yM04AVzAQ7MNMz9WmK3tRENLO5L-IpvEs_0,71
2
+ islamic_content_sdk/client.py,sha256=7SGjzRXCnnWRhC8h-tC3AS5hq7orutFZZ4R9kbjnK20,661
3
+ islamic_content_sdk/services/__init__.py,sha256=RB5fNb6t1tSGDGDfPdNqCZ089_nckMi5p6sPzeoKaDg,24
4
+ islamic_content_sdk/services/al_montaka.py,sha256=F6kR4fn-xoO9vPBmS-i5g5jD-eH8dtapvNkSRwYT0kM,4071
5
+ islamic_content_sdk/services/base.py,sha256=y4Jgys9rKm4fmpVYbqIFXEVed8Mq9RG9hhh0TkJujp4,1510
6
+ islamic_content_sdk/services/bayan_al_islam.py,sha256=9lfeOiRhmWy5uhKxlhm2OGgja4rCIyqkqThbuL182vI,2825
7
+ islamic_content_sdk/services/hadeethenc.py,sha256=m-BL5zHZ0nLIlkVeiy75GnuBBJp1O8lyoGfr-yPaTJY,1521
8
+ islamic_content_sdk/services/islamhouse.py,sha256=Kae0HBNSyOlKuxqge2-GNuccOzsEGGcR3YGntaSTO_8,8084
9
+ islamic_content_sdk/services/quranenc.py,sha256=fiYwjiokBdcLlWKMUWE8LdzkQTupm5YDE6eihs9pKB0,1551
10
+ islamic_content_sdk/services/risalat_al_haramain.py,sha256=p-xo94uF_ZpCQTsCYqKPAgJAzHt6BnMtEBv4CSQhQUc,4363
11
+ islamic_content_sdk-1.0.0.dist-info/METADATA,sha256=UIEghnyo0D0gzKaQ50JG0oas2ZYHWX73MYbCkk7_VWg,16845
12
+ islamic_content_sdk-1.0.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
13
+ islamic_content_sdk-1.0.0.dist-info/top_level.txt,sha256=YwyLzv-OrqzuVo3nCb7Hgnapar_zlJfH2DmJwCs2r5s,20
14
+ islamic_content_sdk-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (70.2.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ islamic_content_sdk