Implemented Topic API and tests

Added (Artist) Topic POST and DELETE calls as well as tests for them. The tests do not include Artist-to-Topic assignment.
master
Peery 2 years ago
parent 245c8737d1
commit 81b069b0f4

@ -6,7 +6,7 @@ import sqlalchemy.orm as db
import sqlalchemy
from sqlalchemy.orm import declarative_base, relationship, load_only
from database.models import Art, ArtnoID, Artist, Presence, TagCategory, TagCategorynoID, TagNoID, Tag
from database.models import Art, ArtnoID, Artist, Presence, TagCategory, TagCategorynoID, TagNoID, Tag, Topic, TopicNoId
# TODO read sensitive data from environment file or similar
SQLALCHEMY_DATABASE_URL = "postgresql://artnet_editor:G606Rm9sFEXe6wfTLxVu@[::1]/test_artnet"
@ -361,6 +361,9 @@ class Database:
# Topic
def get_topic_list(self):
return self.__get_db().query(DBTopic).all() # TODO fix StackOverflow
def get_topic_by_id(self, id: int) -> DBTopic:
result = self.__get_db().query(DBTopic).filter(DBTopic.id == id).first()
return result
@ -369,10 +372,37 @@ class Database:
result = self.__get_db().query(DBTopic).filter(func.lower(DBTopic.name) == name.lower()).first()
return result
def update_topic(self, name: str, description: str):
raise NotImplementedError
def create_topic_by_model(self, topic: TopicNoId):
if not isinstance(topic.name, str) and len(topic.name) > 2:
raise ValueError("Topic name must be at least 2 letters long!")
def delete_topic(self, name: str):
if self.get_topic_by_name(topic.name) is not None:
raise ValueError(f"Topic name must be unique! '{topic.name}' already exists!")
db_topic = DBTopic(name=topic.name, description=topic.description)
db = self.__get_db()
db.add(db_topic)
db.commit()
return db_topic
def update_topic_by_model(self, topic: Topic):
db_topic = self.get_topic_by_id(topic.id)
db_topic.name = topic.name
db_topic.description = topic.description
self.__get_db().commit()
return db_topic
def delete_topic_by_id(self, id: int):
db_topic = self.get_topic_by_id(id)
self.__get_db().delete(db_topic)
self.__get_db().commit()
def delete_topic_by_name(self, name: str):
raise NotImplementedError
# Artist -> Topic

@ -11,7 +11,7 @@ class TopicNoId(BaseModel):
class Topic(TopicNoId):
topic_id: int
id: int
class ArtistNoId(BaseModel):

@ -5,7 +5,7 @@ from typing import List, Tuple
from database.database import Database
from database.database import DBPresence, DBArt2Presence
from database.models import Art, ArtnoID, Presence, ArtistNoId, Tag, TagNoID, TagCategory, TagCategorynoID
from database.models import Art, ArtnoID, Presence, ArtistNoId, Tag, TagNoID, TagCategory, TagCategorynoID, TopicNoId, Topic
app = FastAPI()
db = Database()
@ -198,10 +198,10 @@ async def artist(id: int):
async def topic(name: str = None, id: int = None, artist_id: int = None):
name = unquote(name) if name is not None else None
print(f"Received GET on /artnet/metadata/topic (name={name}, id={id}, artist_id={artist_id})")
if name is None and id is None and artist_id is None:
raise HTTPException(status_code=406)
result = None
if name is None and id is None and artist_id is None:
result = db.get_topic_list()
if name is not None or id is not None:
if id is not None:
result = db.get_topic_by_id(id)
@ -221,6 +221,30 @@ async def topic(name: str = None, id: int = None, artist_id: int = None):
raise HTTPException(status_code=404, detail="Topic was not found!")
@app.post("/artnet/metadata/topic")
async def topic(topic: TopicNoId, id: int = None):
print(f"Received POST on /artnet/metadata/topic (id={id}) body: topic={topic}")
if id is None: # creating new topic
try:
new_id = db.create_topic_by_model(topic).id
return {"id": new_id}
except ValueError as e:
raise HTTPException(status_code=406, detail=str(e))
else: # updating topic
topic_ = Topic(name=topic.name, description=topic.description, id=id)
db.update_topic_by_model(topic_)
@app.delete("/artnet/metadata/topic")
async def topic(id: int):
print(f"Received DELETE on /artnet/metadata/topic (id={id})")
if db.get_topic_by_id(id) is None:
raise HTTPException(status_code=404, detail="No topic with this id could be found!")
db.delete_topic_by_id(id)
@app.get("/artnet/metadata/tag")
async def tag(id: int = None, name: str = None, fuzzy: bool = False, category: int = None):
name = unquote(name) if name is not None else None

@ -174,7 +174,7 @@ def run_tag_test(url: str, port: int):
print(f"Found {len(list_tags(url, port))} tag entries!")
print("Deleting the tag entries ...")
delete_tag_entries(url, port) # would throw an exception if an error occurred
delete_tag_result = True
delete_tag_result = False if not len(list_tags(url, port)) == 0 else True
print(f"Found {len(list_tags(url, port))} tag entries!")
# Clean up

@ -0,0 +1,131 @@
import requests
import json
from typing import List, Tuple
from tests.createAPI.create_delete_artist import create_artist_entries, test_artist_entries, delete_artist_entries, \
list_artists
test_topic_entries = [{"name": "topic_name1", "description": "description1", "id": None, "artists": [0, 1]},
{"name": "topic_name2", "description": "description2", "id": None, "artists": [1, 2]}]
def create_topic_entries(url: str, port: int):
"""
Create many topic entries for testing purposes
:param url:
:param port:
:return:
"""
for i in range(len(test_topic_entries)):
r = create_topic(url, port, name=test_topic_entries[i]["name"], desc=test_topic_entries[i]["description"])
if r.status_code != 200:
print(f"Create Topic Entry Test Nr.{i}: failed with {r.status_code} and reason {r.text}")
raise Exception("Create Topic Entry Test: FAILED")
else:
test_topic_entries[i]["id"] = json.loads(r.text)["id"]
def update_topic_entries(url: str, port: int):
for i in range(len(test_topic_entries)):
new_name = test_topic_entries[i]["name"] + "_updated"
new_description = test_topic_entries[i]["description"] + "_updated"
r = update_topic(url, port, id=test_topic_entries[i]["id"], name=new_name, desc=new_description)
if r.status_code != 200:
print(f"Updating Topuc Entry Test Nr.{i}: failed with {r.status_code} and reason {r.text}")
raise Exception("Update Topic Entry Test: FAILED")
topic = get_topic_by_id(url, port, test_topic_entries[i]["id"])
if not topic["name"] == new_name:
print(f"Name is not matching the expected one! "
f"Current: {topic['name']} Expceted: {new_name}")
raise Exception("Update Topic Entry Test: FAILED")
if not topic["description"] == new_description:
print(f"Description is not matching the expected one! "
f"Current: {topic['description']} Expceted: {new_description}")
raise Exception("Update Topic Entry Test: FAILED")
def delete_topic_entries(url: str, port: int):
for i in range(len(test_topic_entries)):
r = delete_topic(url, port, id=test_topic_entries[i]["id"])
if r.status_code != 200:
print(f"Delete Topic Entry Test Nr.{i}: failed with {r.status_code} and reason {r.text}")
raise Exception("Delete Topic Entry Test: FAILED")
def delete_all_topics(url: str, port: int):
topics = list_topics(url, port)
print(f"Removing following topics: {topics}")
for topic in topics:
delete_topic(url, port, id=topic["id"])
def list_topics(url: str, port: int):
r = requests.get(f"http://{url}:{port}/artnet/metadata/topic")
if r.status_code != 200:
raise Exception(f"Failed querying for topics! Status: {r.status_code} Reason: {r.text}")
topics = json.loads(r.text)
return topics
def get_topic_by_id(url: str, port: int, id: str):
r = requests.get(f"http://{url}:{port}/artnet/metadata/topic?id={id}")
if r.status_code != 200:
raise Exception("Failed querying for topic!")
return json.loads(r.text)
def create_topic(url: str, port: int, name: str, desc: str):
r = requests.post(f"http://{url}:{port}/artnet/metadata/topic",
json={"name": name, "description": desc})
return r
def update_topic(url: str, port: int, id: str, name: str = None, desc: str = None):
r = requests.post(f"http://{url}:{port}/artnet/metadata/topic?id={id}",
json={"name": name, "description": desc})
return r
def delete_topic(url: str, port: int, id: str):
r = requests.delete(f"http://{url}:{port}/artnet/metadata/topic?id={id}")
return r
def run_topic_tests(url: str, port: int):
print()
print("----------------")
l = len(list_topics(url, port))
print(f"Starting topic tests with ({l}) topics!")
if l > 0:
print("Deleting leftover topics ...")
delete_all_topics(url, port)
print(f"Creating {len(test_topic_entries)} topic entries for the test ...")
create_topic_entries(url, port)
create_topic_result = False if not len(test_topic_entries) == len(list_topics(url, port)) else True
print(f"Found {len(list_topics(url, port))} topic entries!")
print("Updating topic entries with new data now ...")
update_topic_entries(url, port) # throws exception if not working
update_topic_result = True
print("Finished updating the topic entries.")
print(f"Found {len(list_topics(url, port))} topic entries!")
print(f"Deleting all topic entries ...")
delete_topic_entries(url, port)
delete_topic_result = False if not len(list_topics(url, port)) == 0 else True
print(f"Found {len(list_topics(url, port))} topic entries!")
print("Finished topic tests!")
return create_topic_result, update_topic_result, delete_topic_result
if __name__ == "__main__":
url, port = "127.0.0.1", 8000
run_topic_tests(url, port)

@ -2,7 +2,8 @@ from tests.createAPI.create_delete_art import run_art_test, list_art, delete_art
from tests.createAPI.create_delete_presence import run_presence_test, list_presences
from tests.createAPI.create_delete_artist import delete_artist_entries, list_artists, run_artist_test
from tests.createAPI.create_delete_tag_category import delete_category_entries, list_tag_categories, run_tag_category_test
from tests.createAPI.create_delete_tag import create_tag_entries, list_tags, run_tag_test, delete_tag_entries
from tests.createAPI.create_delete_tag import list_tags, run_tag_test, delete_tag_entries
from tests.createAPI.create_delete_topic import list_topics, run_topic_tests, delete_all_topics
from tests.relationAPI.relate_art import run_art_presence_relation_test
@ -33,6 +34,7 @@ def run_tests(url: str, port: int):
create_art2presence_result, delete_art2presence_result = run_art_presence_relation_test(url, port)
create_category_result, update_category_result, delete_category_result = run_tag_category_test(url, port)
create_tag_result, update_tag_result, delete_tag_result = run_tag_test(url, port)
create_topic_result, update_topic_result, delete_topic_result = run_topic_tests(url, port)
print()
print("-------- Test Results ---------")
@ -47,6 +49,9 @@ def run_tests(url: str, port: int):
print(f"Tag Categories: {len(r)}, {r}")
r = list_tags(url, port)
print(f"Tags: {len(r)}, {r}")
r = list_topics(url, port)
print(f"Topics: {len(r)}, {r}")
print()
print("Functions:")
print(f"Artists: \t\t\t\tCreate: {create_artist_result} \tUpdate: {'N/A'} "
@ -61,7 +66,8 @@ def run_tests(url: str, port: int):
f"\tDelete: {delete_category_result} \t(Direct)")
print(f"Tag: \t\t\t\t\tCreate: {create_tag_result} \tUpdate: {update_tag_result} "
f"\tDelete: {delete_tag_result} \t(Direct)")
print(f"(Artist) Topic: \t\tN/A")
print(f"(Artist) Topic: \t\tCreate: {create_topic_result} \tUpdate: {update_topic_result} "
f"\tDelete: {delete_topic_result} \t(Direct)")
print(f"Art Collection: \t\tN/A")
print(f"Art2Art Collection: \tN/A")
print(f"Artist2Topic: \t\t\tN/A")

Loading…
Cancel
Save