11import logging
22
33from fastapi import APIRouter , Depends , HTTPException , Query , status
4- from sqlalchemy import not_
54from sqlalchemy .exc import SQLAlchemyError
65from sqlalchemy .orm import Session
76
87from api .db .database import get_db
9- from api .v1 .models .blog import Blog
108from api .v1 .schemas .blog import (
119 BlogCreateSchema ,
12- BlogListItemResponseSchema ,
1310 BlogListResponseSchema ,
1411 BlogResponseSchema ,
1512 BlogUpdateSchema ,
1613)
14+ from api .v1 .services .blog import BlogService
1715
1816blog = APIRouter (prefix = "/blogs" , tags = ["Blog" ])
1917
@@ -30,45 +28,19 @@ async def create_blog(
3028 db : Session = Depends (get_db ),
3129) -> BlogResponseSchema :
3230 try :
33- existing_blog = db .query (Blog ).filter (Blog .title == blog .title ).first ()
34- if existing_blog :
35- logger .warning (f"Blog post with title '{ blog .title } ' already exists." )
36- raise HTTPException (
37- status_code = status .HTTP_409_CONFLICT ,
38- detail = "A blog post with this title already exists." ,
39- )
40-
41- new_blog = Blog (
42- title = blog .title ,
43- excerpt = blog .excerpt ,
44- content = blog .content ,
45- image_url = blog .image_url ,
46- )
47- db .add (new_blog )
48- db .commit ()
49- db .refresh (new_blog )
50- logger .info (f"Blog post '{ new_blog .title } ' created successfully." )
51-
52- return BlogResponseSchema (
53- id = new_blog .id ,
54- title = new_blog .title ,
55- excerpt = new_blog .excerpt ,
56- content = new_blog .content ,
57- image_url = new_blog .image_url ,
58- created_at = new_blog .created_at ,
59- updated_at = new_blog .updated_at ,
31+ return BlogService .create_blog (db , blog )
32+ except ValueError as e :
33+ logger .warning (str (e ))
34+ raise HTTPException (
35+ status_code = status .HTTP_409_CONFLICT ,
36+ detail = str (e ),
6037 )
61-
62- except HTTPException as http_err :
63- raise http_err
64-
65- except SQLAlchemyError as sql_err :
66- logger .error (f"Database error occurred: { sql_err } " )
38+ except SQLAlchemyError as e :
39+ logger .error (f"Database error occurred: { e } " )
6740 raise HTTPException (
6841 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
6942 detail = "Database error occurred." ,
7043 )
71-
7244 except Exception as e :
7345 logger .error (f"Internal server error: { e } " )
7446 raise HTTPException (
@@ -88,41 +60,7 @@ async def list_blog(
8860 db : Session = Depends (get_db ),
8961) -> BlogListResponseSchema :
9062 try :
91- offset = (page - 1 ) * page_size
92- query = (
93- db .query (Blog )
94- .filter (not_ (Blog .is_deleted ))
95- .order_by (Blog .created_at .desc ())
96- )
97- total_count = query .count ()
98- blogs = query .offset (offset ).limit (page_size ).all ()
99-
100- next_page = None
101- if offset + page_size < total_count :
102- next_page = f"/api/v1/blogs?page={ page + 1 } &page_size={ page_size } "
103-
104- prev_page = None
105- if page > 1 :
106- prev_page = f"/api/v1/blogs?page={ page - 1 } &page_size={ page_size } "
107-
108- results = [
109- BlogListItemResponseSchema (
110- id = blog .id ,
111- title = blog .title ,
112- excerpt = blog .excerpt ,
113- image_url = blog .image_url ,
114- created_at = blog .created_at ,
115- )
116- for blog in blogs
117- ]
118-
119- return BlogListResponseSchema (
120- count = total_count ,
121- next = next_page ,
122- previous = prev_page ,
123- results = results ,
124- )
125-
63+ return BlogService .list_blog (db , page , page_size )
12664 except SQLAlchemyError as e :
12765 logger .error (f"Database error occurred: { e } " )
12866 raise HTTPException (
@@ -147,27 +85,13 @@ async def read_blog(
14785 db : Session = Depends (get_db ),
14886) -> BlogResponseSchema :
14987 try :
150- blog = (
151- db .query (Blog )
152- .filter (
153- Blog .id == id ,
154- not_ (Blog .is_deleted ),
155- )
156- .first ()
88+ return BlogService .read_blog (db , id )
89+ except ValueError as e :
90+ logger .warning (str (e ))
91+ raise HTTPException (
92+ status_code = status .HTTP_404_NOT_FOUND ,
93+ detail = str (e ),
15794 )
158- if not blog :
159- logger .warning (f"Blog post with ID '{ id } ' not found." )
160- raise HTTPException (
161- status_code = status .HTTP_404_NOT_FOUND ,
162- detail = "Blog post not found." ,
163- )
164-
165- logger .info (f"Blog post with ID '{ id } ' retrieved successfully." )
166- return BlogResponseSchema .model_validate (blog .__dict__ )
167-
168- except HTTPException as http_err :
169- raise http_err
170-
17195 except SQLAlchemyError as e :
17296 logger .error (f"Database error occurred: { e } " )
17397 raise HTTPException (
@@ -187,81 +111,29 @@ async def read_blog(
187111 response_model = BlogResponseSchema ,
188112 status_code = status .HTTP_200_OK ,
189113)
190- def update_blog (
114+ async def update_blog (
191115 id : int ,
192116 blog_update : BlogUpdateSchema ,
193117 db : Session = Depends (get_db ),
194118) -> BlogResponseSchema :
195119 try :
196- # Fetch the blog post to be updated
197- blog = (
198- db .query (Blog )
199- .filter (
200- Blog .id == id ,
201- not_ (Blog .is_deleted ),
202- )
203- .first ()
204- )
205- if not blog :
206- raise HTTPException (
207- status_code = status .HTTP_404_NOT_FOUND ,
208- detail = "Blog post not found." ,
209- )
210-
211- # Get the updated data
212- update_data = blog_update .model_dump (exclude_unset = True )
213-
214- # Check for title uniqueness
215- if "title" in update_data and update_data ["title" ] != blog .title :
216- existing_blog = (
217- db .query (Blog )
218- .filter (
219- Blog .title == update_data ["title" ],
220- not_ (Blog .is_deleted ),
221- )
222- .first ()
223- )
224- if existing_blog :
225- logger .warning (
226- f"Blog post with title '{ update_data ['title' ]} ' already exists."
227- )
228- raise HTTPException (
229- status_code = status .HTTP_409_CONFLICT ,
230- detail = "A blog post with this title already exists." ,
231- )
232-
233- # Update fields if they are provided
234- for field , value in update_data .items ():
235- setattr (blog , field , value )
236-
237- db .commit ()
238- db .refresh (blog )
239- logger .info (f"Blog post '{ blog .title } ' updated successfully." )
240-
241- return BlogResponseSchema (
242- id = blog .id ,
243- title = blog .title ,
244- excerpt = blog .excerpt ,
245- content = blog .content ,
246- image_url = blog .image_url ,
247- created_at = blog .created_at ,
248- updated_at = blog .updated_at ,
120+ return BlogService .update_blog (db , id , blog_update )
121+ except ValueError as e :
122+ logger .warning (str (e ))
123+ raise HTTPException (
124+ status_code = status .HTTP_404_NOT_FOUND
125+ if "not found" in str (e ).lower ()
126+ else status .HTTP_409_CONFLICT ,
127+ detail = str (e ),
249128 )
250-
251- except HTTPException as http_err :
252- raise http_err
253-
254- except SQLAlchemyError as sql_err :
255- logger .error (f"Database error occurred: { sql_err } " )
256- db .rollback ()
129+ except SQLAlchemyError as e :
130+ logger .error (f"Database error occurred: { e } " )
257131 raise HTTPException (
258132 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
259133 detail = "Database error occurred." ,
260134 )
261-
262135 except Exception as e :
263136 logger .error (f"Internal server error: { e } " )
264- db .rollback ()
265137 raise HTTPException (
266138 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
267139 detail = "Internal server error." ,
@@ -277,39 +149,21 @@ async def delete_blog(
277149 db : Session = Depends (get_db ),
278150) -> None :
279151 try :
280- blog_to_delete = (
281- db .query (Blog )
282- .filter (
283- Blog .id == id ,
284- not_ (Blog .is_deleted ),
285- )
286- .first ()
152+ BlogService .delete_blog (db , id )
153+ except ValueError as e :
154+ logger .warning (str (e ))
155+ raise HTTPException (
156+ status_code = status .HTTP_404_NOT_FOUND ,
157+ detail = str (e ),
287158 )
288- if not blog_to_delete :
289- logger .warning (f"Blog post with ID '{ id } ' not found." )
290- raise HTTPException (
291- status_code = status .HTTP_404_NOT_FOUND ,
292- detail = "Blog post with given id not found." ,
293- )
294-
295- blog_to_delete .is_deleted = True
296- db .commit ()
297- logger .info (f"Blog post '{ blog_to_delete .title } ' deleted successfully." )
298-
299- except HTTPException as http_err :
300- raise http_err
301-
302159 except SQLAlchemyError as e :
303160 logger .error (f"Database error occurred: { e } " )
304- db .rollback ()
305161 raise HTTPException (
306162 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
307163 detail = "Database error occurred." ,
308164 )
309-
310165 except Exception as e :
311166 logger .error (f"Internal server error: { e } " )
312- db .rollback ()
313167 raise HTTPException (
314168 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
315169 detail = "Internal server error." ,
0 commit comments