from fastapi import FastAPI, HTTPException import uvicorn from typing import List, Tuple from database.database import Database from database.models import Art, ArtnoID, Presence, ArtistNoId app = FastAPI() db = Database() @app.get("/artnet/metadata/art") async def art(id: int = None, hash: str = None, tag_id: int = None): print(f"Received GET on /artnet/metadata/art (id={id}, hash={hash}, tag_id={tag_id})") #if id is None and hash is None and tag_id is None: #raise HTTPException(status_code=406, detail="requires id or hash param") result = None if id is not None: result = db.get_art_by_id(id) elif hash is not None: result = db.get_art_by_hash(hash) elif tag_id is not None: result = db.get_tag_art(tag_id) if id is None and hash is None and tag_id is None: # TODO fix against listing enormous amounts of art (because all could be large) result = db.get_art_list() if result is not None: return result raise HTTPException(status_code=404, detail="Art was not found!") @app.post("/artnet/metadata/art") async def art(art: ArtnoID, id: int = None): print(f"Received POST on /artnet/metadata/art (id={id}) body: art=({art})") if id is None: # create new art entry if art.presences is None: # tried to create art without any presence raise HTTPException(status_code=422, detail="No presences were listed") try: for presence in art.presences: r = db.get_presence(name=presence.name, domain=presence.domain) #if db.get_presence(name=presence.name, domain=presence.domain) is None: # raise HTTPException(status_code=422, # detail=f"Presence ({presence.name}, {presence.domain}) is unknown!") #db.create # create presence-art relationship # TODO validate & create presence-art relationship new_id = db.create_art_by_model(art) return {"id": new_id} except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) else: # update existing art entry if db.get_art_by_id(id) is None: return HTTPException(status_code=404, detail="The specified art could not be found!") # TODO implement linking to one or multiple presences # TODO enforcing at least one presence updated_art = Art(id=id) updated_art.hash = art.hash updated_art.link = art.link updated_art.title = art.title updated_art.path = art.path db.update_art_by_model(updated_art) return True @app.delete("/artnet/metadata/art") async def art(id: int): print(f"Received DELETE on /artnet/metadata/art (id={id})") if db.get_art_by_id(id) is None: raise HTTPException(status_code=404, detail="Art has not been found!") db.delete_art_by_id(id) @app.get("/artnet/metadata/presence") async def presence(name: str = None, domain: str = None, artist_id: int = None, art_id: int = None, art_md5: str = None): print(f"Received GET on /artnet/metadata/presence (name={name}, domain={domain}, artist_id={artist_id}" f", art_id={art_id}, art_md5={art_md5})") result = None if artist_id is not None and name is None and domain is None: result = db.get_artist_presences(artist_id) elif art_id is not None and name is None and domain is None: result = db.get_art_presences_by_id(art_id) elif art_md5 is not None and name is None and domain is None: result = db.get_art_presences_by_hash(art_md5) elif name is not None and domain is not None: result = db.get_presence(name, domain) if name is None and domain is None and artist_id is None and art_id is None and art_md5 is None: result = db.get_presence_list() #raise HTTPException(status_code=406, detail="You must query with at least one parameter!") if result is not None: return result raise HTTPException(status_code=404, detail="Presence was not found!") @app.post("/artnet/metadata/presence") async def presence(presence: Presence): print(f"Received POST on /artnet/metadata/presence body: presence={presence}") curr_presence = db.get_presence(name=presence.name, domain=presence.domain) r = db.get_artist(presence.artist_id) if r is None: raise HTTPException(status_code=406, detail="Invalid Artist ID! Could not find artist.") if curr_presence is None: # must be new presence db.create_presence(name=presence.name, domain=presence.domain, artist_id=presence.artist_id, link=presence.link) else: # editing current presence db.update_presence(name=curr_presence.name, domain=curr_presence.domain, artist_id=presence.artist_id, link=presence.link) @app.delete("/artnet/metadata/presence") async def presence(name: str, domain: str): print(f"Received DELETE on /artnet/metadata/presence (name={name}, domain={domain})") if db.get_presence(name, domain) is None: raise HTTPException(status_code=404, detail="Presence has not been found!") db.delete_presence(name, domain) @app.get("/artnet/metadata/artist") async def artist(id: int = None, topic_id: int = None, description: str = None): print(f"Received GET on /artnet/metadata/artist (id={id}, topic_id={topic_id}, description={description})") result = None if id is None and topic_id is None and description is None: result = db.get_artist_list() if id is not None: result = db.get_artist(id) elif topic_id is not None: result = db.get_topic_artists(topic_id) elif description is not None: result = db.search_artist(description) if result is not None: return result raise HTTPException(status_code=404, detail="Artist was not found!") @app.post("/artnet/metadata/artist") async def artist(artist: ArtistNoId, id: int = None): print(f"Received POST on /artnet/metadata/artist (id={id}) body: artist={artist}") if id is None: # create new artist db_artist = db.create_artist(name=artist.description, topics=artist.topics) return db_artist.id else: if db.get_artist(id) is not None: db.update_artist(artist_id=id, name=artist.description, topics=artist.topics) else: raise HTTPException(status_code=404, detail="Tried to edit unknown artist. ID was not found!") @app.delete("/artnet/metadata/artist") async def artist(id: int): print(f"Received DELETE on /artnet/metadata/artist (id={id})") if db.get_artist(id) is None: raise HTTPException(status_code=404, detail="Tried to delete unknown artist. ID was not found!") db.delete_artist(id) @app.get("/artnet/metadata/topic") async def topic(name: str = None, id: int = None, artist_id: int = 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 not None or id is not None: if id is not None: result = db.get_topic_by_id(id) elif name is not None: result = db.get_topic_by_name(name) elif artist_id is not None: result = db.get_artist_topics(artist_id) if result is not None: return result raise HTTPException(status_code=404, detail="Topic was not found!") @app.get("/artnet/metadata/tag") async def tag(id: int = None, name: str = None, fuzzy: bool = False, category: int = None): if id is None and name is None and category is None: raise HTTPException(status_code=406) result = None if fuzzy: if name is not None: result = db.search_tag_by_name_fuzzy(name) if result is not None: return result raise HTTPException(status_code=404, detail="No matching tag found!") else: if id is not None: result = db.get_tag_by_id(id) elif name is not None: result = db.get_tag_by_name(name) elif category is not None: result = db.get_category_tags(category) if result is not None: return result raise HTTPException(status_code=404, detail="Tag was not found!") @app.get("/artnet/metadata/category") async def category(name: str = None, id: int = None): if name is None and id is None: raise HTTPException(status_code=406) result = None if id is not None: result = db.get_category_by_id(id) elif name is not None: result = db.get_category_by_name(name) if result is not None: return result raise HTTPException(status_code=404, detail="Category not found!") if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000)