@@ -15,12 +15,12 @@ class Api:
1515 """
1616
1717 def __init__ (
18- self ,
19- email : str ,
20- password : str ,
21- base_url : str | None = None ,
22- publication_url : str | None = None ,
23- debug : bool = False ,
18+ self ,
19+ email : str | None = None ,
20+ password : str | None = None ,
21+ base_url : str | None = None ,
22+ publication_url : str | None = None ,
23+ debug : bool = False ,
2424 ):
2525 """
2626
@@ -42,14 +42,17 @@ def __init__(
4242 logging .basicConfig ()
4343 logging .getLogger ().setLevel (logging .DEBUG )
4444
45- self ._init_session (email , password )
45+ self ._session = requests .Session ()
46+
47+ if email is not None and password is not None :
48+ self .login (email , password )
4649
4750 def login (self , email : str , password : str ) -> dict :
4851 """
4952
5053 Args:
51- email:
52- password:
54+ email: substack account email
55+ password: substack account password
5356 """
5457
5558 response = self ._session .post (
@@ -64,11 +67,6 @@ def login(self, email: str, password: str) -> dict:
6467 )
6568 return Api ._handle_response (response = response )
6669
67- def _init_session (self , email , password ):
68- self ._session = requests .Session ()
69-
70- self .login (email , password )
71-
7270 @staticmethod
7371 def _handle_response (response : requests .Response ):
7472 """
@@ -112,11 +110,11 @@ def get_drafts(self, filter: str = None, offset: int = None, limit: int = None):
112110 return Api ._handle_response (response = response )
113111
114112 def post_draft (
115- self ,
116- draft_bylines : list ,
117- title : str = None ,
118- subtitle : str = None ,
119- body : str = None ,
113+ self ,
114+ draft_bylines : list ,
115+ title : str = None ,
116+ subtitle : str = None ,
117+ body : str = None ,
120118 ) -> dict :
121119 """
122120
@@ -141,12 +139,12 @@ def post_draft(
141139 return Api ._handle_response (response = response )
142140
143141 def put_draft (
144- self ,
145- draft : str ,
146- title : str = None ,
147- subtitle : str = None ,
148- body : str = None ,
149- cover_image : str = None ,
142+ self ,
143+ draft : str ,
144+ title : str = None ,
145+ subtitle : str = None ,
146+ body : str = None ,
147+ cover_image : str = None ,
150148 ) -> dict :
151149 """
152150
@@ -188,7 +186,7 @@ def prepublish_draft(self, draft: str) -> dict:
188186 return Api ._handle_response (response = response )
189187
190188 def publish_draft (
191- self , draft : str , send : bool = True , share_automatically : bool = False
189+ self , draft : str , send : bool = True , share_automatically : bool = False
192190 ) -> dict :
193191 """
194192
@@ -205,3 +203,50 @@ def publish_draft(
205203 json = {"send" : send , "share_automatically" : share_automatically },
206204 )
207205 return Api ._handle_response (response = response )
206+
207+ def get_categories (self ):
208+ """
209+
210+ Retrieve list of all available categories.
211+
212+ Returns:
213+
214+ """
215+ response = self ._session .get (f"{ self .base_url } /categories" )
216+ return Api ._handle_response (response = response )
217+
218+ def get_category (self , category_id : int , category_type : str , page : int ):
219+ response = self ._session .get (f"{ self .base_url } /category/public/{ category_id } /{ category_type } " ,
220+ params = {"page" : page })
221+ return Api ._handle_response (response = response )
222+
223+ def get_single_category (self , category_id : int , category_type : str , page : int | None = None ,
224+ limit : int | None = None ):
225+ """
226+
227+ Args:
228+ category_id:
229+ category_type: paid or all
230+ page: by default substack retrieves only the first 25 publications in the category. If this is left None,
231+ then all pages will be retrieved. The page size is 25 publications.
232+ limit:
233+ Returns:
234+
235+ """
236+ if page is not None :
237+ output = self .get_category (category_id , category_type , page )
238+ else :
239+ publications = []
240+ page = 0
241+ while True :
242+ page_output = self .get_category (category_id , category_type , page )
243+ publications .extend (page_output .get ("publications" , []))
244+ if (limit is not None and limit <= len (publications )) or not page_output .get ("more" , False ):
245+ publications = publications [:limit ]
246+ break
247+ page += 1
248+ output = {
249+ "publications" : publications ,
250+ "more" : page_output .get ("more" , False )
251+ }
252+ return output
0 commit comments