You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.4 KiB
Python

import os
from apistar import Route, http, App
from sqlalchemy import create_engine
from .models import NewsArticle, NewsSource
from .schema import NewsSourceSchema, NewsArticleSchema
from .util import Session, SQLAlchemySession, SQLAlchemyHook
news_source_schema = NewsSourceSchema()
news_article_schema = NewsArticleSchema()
def get_sources(session: Session):
"""Retrieves all News Sources"""
sources = session.query(NewsSource).all()
return http.JSONResponse(news_source_schema.dump(sources, many=True).data, status_code=200)
def add_source(session: Session, request_data: http.RequestData, app: App):
"""Adds a single source to the News Source collection"""
news_source_data, errors = news_source_schema.load(request_data)
if errors:
msg = {"message": "400 Bad Request", "error": errors}
return http.JSONResponse(msg, status_code=400)
news_source = NewsSource(**news_source_data)
session.add(news_source)
session.flush()
headers = {"Location": app.reverse_url('get_source', id=news_source.id)}
session.commit()
return http.JSONResponse(news_source_schema.dump(news_source).data, status_code=201, headers=headers)
def delete_source(session: Session, id: int):
"""Delete a single News Source from the collection by id"""
news_source = session.query(NewsSource).filter_by(id=id).one_or_none()
if news_source is None:
msg = {"message": "404 Not Found"}
return http.JSONResponse(msg, status_code=404)
session.delete(news_source)
session.commit()
msg = {"message": "200 OK"}
return http.JSONResponse(msg, status_code=200)
def get_source(session: Session, id: int):
"""Retrieves a single News Source by id"""
news_source = session.query(NewsSource).filter_by(id=id).one_or_none()
if news_source is None:
msg = {"message": "404 Not Found"}
return http.JSONResponse(msg, status_code=404)
return http.JSONResponse(news_source_schema.dump(news_source).data, status_code=200)
def get_articles(session: Session):
"""Retrieves all articles"""
articles = session.query(NewsArticle).all()
return http.JSONResponse(news_article_schema.dump(articles, many=True).data, status_code=200)
def get_article(session: Session, id: int):
"""Retrieves a single article by id"""
news_article = session.query(NewsArticle).filter_by(id=id).one_or_none()
if news_article is None:
msg = {"message": "404 Not Found"}
return http.JSONResponse(msg, status_code=404)
return http.JSONResponse(news_article_schema.dump(news_article).data, status_code=200)
def add_article(session: Session, request_data: http.RequestData, app: App):
"""Adds a single article"""
news_article_data, errors = news_article_schema.load(request_data)
if errors:
msg = {"message": "400 Bad Request", "error": errors}
return http.JSONResponse(msg, status_code=400)
news_article = NewsArticle(**news_article_data)
session.add(news_article)
session.flush()
headers = {"Location": app.reverse_url('get_article', id=news_article.id)}
session.commit()
return http.JSONResponse(news_article_schema.dump(news_article).data, status_code=201, headers=headers)
def delete_article(session: Session, id):
"""Delete a single News Sources from the collection by id"""
news_article = session.query(NewsArticle).filter_by(id=id).one_or_none()
if news_article is None:
msg = {"message": "404 Not Found"}
return http.JSONResponse(msg, status_code=404)
session.delete(news_article)
session.commit()
msg = {"message": "200 OK"}
return http.JSONResponse(msg, status_code=200)
routes = [
Route('/sources', 'GET', get_sources),
Route('/sources', 'POST', add_source),
Route('/sources/{id}', 'GET', get_source),
Route('/sources/{id}', 'DELETE', delete_source),
Route('/articles', 'GET', get_articles),
Route('/articles', 'POST', add_article),
Route('/articles/{id}', 'GET', get_article),
Route('/articles/{id}', 'DELETE', delete_article),
]
routes = routes
components = [
SQLAlchemySession(engine=create_engine(os.getenv('NEWS_DB', 'postgresql://apistar:local@localhost/news')))
]
hooks = [SQLAlchemyHook()]
def application_factory():
"""Returns an instance of Cookie API"""
return App(components=components,
event_hooks=hooks,
routes=routes)
if __name__ == "__main__":
app = application_factory()
app.serve('0.0.0.0', 8080, debug=True)