First Commit
- Added a script with all FastAPI methods - Added a main.py file to start everything - Generated a config that grabs data from .env
This commit is contained in:
72
src/APIapp.py
Normal file
72
src/APIapp.py
Normal file
@ -0,0 +1,72 @@
|
||||
import DBwork
|
||||
from fastapi import FastAPI, Response, status
|
||||
from pydantic import BaseModel
|
||||
import psycopg2
|
||||
from json import dumps
|
||||
|
||||
|
||||
schema_name = 'harticle'
|
||||
table_name = 'articles'
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
class Entry(BaseModel):
|
||||
url: str
|
||||
rating: int | None = None
|
||||
|
||||
|
||||
@app.get('/api/ping')
|
||||
async def ping():
|
||||
return {'message': 'pong'}
|
||||
|
||||
|
||||
@app.get('/api/rates')
|
||||
async def get_rates():
|
||||
return dumps(DBwork.get_all_entries())
|
||||
|
||||
|
||||
@app.post('/api/article/rate')
|
||||
async def save_rating(entry: Entry, response: Response):
|
||||
conn, cur = DBwork.set_connection()
|
||||
try:
|
||||
DBwork.add_entry(article_url=entry.url,
|
||||
rating=entry.rating,
|
||||
connection=conn,
|
||||
cursor=cur
|
||||
)
|
||||
message = 'success'
|
||||
except psycopg2.Error:
|
||||
response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
message = 'internal server error'
|
||||
finally:
|
||||
DBwork.close_connection(conn, cur)
|
||||
return {'message': message,
|
||||
'url': entry.url,
|
||||
'rating': entry.rating
|
||||
}
|
||||
|
||||
|
||||
@app.post('/api/article/remove_rate')
|
||||
async def remove_rating(entry: Entry, response: Response):
|
||||
conn, cur = DBwork.set_connection()
|
||||
try:
|
||||
DBwork.delete_entry(entry.url, conn, cur)
|
||||
message = 'success'
|
||||
except psycopg2.Error:
|
||||
response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
message = 'internal server error'
|
||||
finally:
|
||||
DBwork.close_connection(conn, cur)
|
||||
return {'message': message}
|
||||
|
||||
|
||||
@app.post('/api/articles/get')
|
||||
async def megafunc(entry: Entry, response: Response):
|
||||
...
|
||||
|
||||
|
||||
''' MAIN '''
|
||||
async def main():
|
||||
DBwork.schema_creator(schema_name)
|
||||
DBwork.table_creator(schema_name, table_name)
|
||||
|
||||
122
src/DBwork.py
Normal file
122
src/DBwork.py
Normal file
@ -0,0 +1,122 @@
|
||||
import psycopg2
|
||||
import config
|
||||
from loguru import logger
|
||||
|
||||
|
||||
logging_level = config.logging_level
|
||||
logger.add(
|
||||
"sys.stdout",
|
||||
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {file}:{line} - {message}",
|
||||
colorize=True,
|
||||
level=logging_level
|
||||
)
|
||||
|
||||
|
||||
#connection stuff
|
||||
def set_connection():
|
||||
try:
|
||||
connection = psycopg2.connect(
|
||||
dbname = config.db_name,
|
||||
user = config.postgres_user,
|
||||
password = config.postgres_password,
|
||||
host = config.host_name,
|
||||
port = config.port
|
||||
)
|
||||
cursor = connection.cursor()
|
||||
return connection, cursor
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Failed to set connection to the PostgreSQL DB: {e.pgerror}')
|
||||
|
||||
|
||||
def close_connection(connection, cursor):
|
||||
try:
|
||||
cursor.close()
|
||||
connection.close()
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Failed to close PostgreSQL connection: {e.pgerror}')
|
||||
|
||||
|
||||
#actual DB alters
|
||||
def add_entry(article_url, rating):
|
||||
connection, cursor = set_connection()
|
||||
try:
|
||||
cursor.execute("INSERT INTO harticle.articles (article_url, rating) VALUES (%s, %s);", (article_url, rating,))
|
||||
connection.commit()
|
||||
logger.info('An entry has been written to the PGSQL DB successfully')
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Failed to write an entry for article \'{article_url}\': {e.pgerror}')
|
||||
finally:
|
||||
close_connection(connection, cursor)
|
||||
|
||||
|
||||
def delete_entry(article_url, connection, cursor):
|
||||
connection, cursor = set_connection()
|
||||
try:
|
||||
cursor.execute("DELETE FROM harticle.articles WHERE article_url = %s;", (article_url,))
|
||||
connection.commit()
|
||||
logger.info(f'Rating for article \'{article_url}\' was cleared successfully')
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Failed to clear a rating entry for article \'{article_url}\': {e.pgerror}')
|
||||
finally:
|
||||
close_connection(connection, cursor)
|
||||
|
||||
|
||||
# def delete_rating(article_url, connection, cursor):
|
||||
# close_connection(connection, cursor)
|
||||
# try:
|
||||
# cursor.execute("UPDATE harticle.articles SET rating = NULL WHERE article_url = %s;", (article_url,))
|
||||
# connection.commit()
|
||||
# logger.info(f'Rating for article \'{article_url}\' was cleared successfully')
|
||||
# close_connection(connection, cursor)
|
||||
# except psycopg2.Error as e:
|
||||
# logger.error(f'Failed to clear a rating entry for article \'{article_url}\': {e.pgerror}')
|
||||
|
||||
|
||||
def get_all_entries():
|
||||
connection, cursor = set_connection()
|
||||
try:
|
||||
cursor.execute('SELECT article_url, rating FROM harticle.articles;')
|
||||
entries = cursor.fetchall()
|
||||
logger.info('All entry pairs have been retrieved successfully')
|
||||
return entries
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Failed to fetch DB entries: {e.pgerror}')
|
||||
finally:
|
||||
close_connection(connection, cursor)
|
||||
|
||||
|
||||
#'create if no any' type functions for schema and table
|
||||
def schema_creator(schema_name):
|
||||
conn, cur = set_connection()
|
||||
try:
|
||||
cur.execute(f'CREATE SCHEMA IF NOT EXISTS {schema_name};')
|
||||
conn.commit()
|
||||
logger.info(f'Successfully created schema {schema_name} if it didn\'t exist yet')
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Error during schema creation: {e}')
|
||||
finally:
|
||||
close_connection(conn, cur)
|
||||
|
||||
|
||||
def table_creator(schema_name, table_name):
|
||||
conn, cur = set_connection()
|
||||
try:
|
||||
cur.execute(f'''
|
||||
CREATE TABLE IF NOT EXISTS {schema_name}.{table_name}
|
||||
(
|
||||
id SERIAL PRIMARY KEY,
|
||||
article_url VARCHAR(3000) UNIQUE NOT NULL,
|
||||
rating INT CHECK (rating < 2)
|
||||
)
|
||||
|
||||
TABLESPACE pg_default;
|
||||
|
||||
ALTER TABLE IF EXISTS {schema_name}.{table_name}
|
||||
OWNER to {config.postgres_user};
|
||||
''')
|
||||
conn.commit()
|
||||
logger.info(f'Successfully created table {table_name} in schema {schema_name} if it didn\'t exist yet')
|
||||
except psycopg2.Error as e:
|
||||
logger.error(f'Error during table creation: {e}')
|
||||
finally:
|
||||
close_connection(conn, cur)
|
||||
9
src/config.py
Normal file
9
src/config.py
Normal file
@ -0,0 +1,9 @@
|
||||
from decouple import config
|
||||
|
||||
|
||||
db_name = config('DB_NAME')
|
||||
postgres_user = config('POSTGRES_USER')
|
||||
postgres_password = config('POSTGRES_PASSWORD')
|
||||
host_name = config('HOST_NAME')
|
||||
port = config('PORT')
|
||||
logging_level = config('LOGGING_LEVEL')
|
||||
7
src/main.py
Normal file
7
src/main.py
Normal file
@ -0,0 +1,7 @@
|
||||
import asyncio
|
||||
import APIapp
|
||||
import uvicorn
|
||||
|
||||
|
||||
asyncio.run(APIapp.main())
|
||||
uvicorn.run("APIapp:app", host="127.0.0.1", port=8000, log_level="info")
|
||||
Reference in New Issue
Block a user