From 78848e062fe3d57226bc6fff5d087fb81d481690 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 17 May 2023 16:08:33 +0700 Subject: [PATCH] Initial commit. API already works --- .dir-locals.el | 1 + .gitignore | 3 +++ api.py | 48 +++++++++++++++++++++++++++++++++++++++++++++ api.restclient | 50 +++++++++++++++++++++++++++++++++++++++++++++++ client/index.html | 16 +++++++++++++++ client/main.css | 3 +++ client/main.js | 0 requirements.txt | 3 +++ 8 files changed, 124 insertions(+) create mode 100644 .dir-locals.el create mode 100644 .gitignore create mode 100644 api.py create mode 100644 api.restclient create mode 100644 client/index.html create mode 100644 client/main.css create mode 100644 client/main.js create mode 100644 requirements.txt diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..2b0024b --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1 @@ +((nil . ((eval . (set-frame-name "Zip My Link"))))) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..572fede --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +venv +__pycache__ diff --git a/api.py b/api.py new file mode 100644 index 0000000..15788e5 --- /dev/null +++ b/api.py @@ -0,0 +1,48 @@ +from fastapi import FastAPI, Response +from fastapi.responses import RedirectResponse +import couchdb +import uuid + +app = FastAPI() + +couch = couchdb.Server("http://admin:password@127.0.0.1:5984") + +@app.get("/{url_id}", status_code=301) +async def redirect_urls(url_id): + target_url = couch["urls"][url_id].get('full_url') + return RedirectResponse(target_url) + +# TODO: Get JWT tokens working and use that to return only the user's urls +# TODO: Look into how FastAPI handles the Authentication header +@app.get("/api/v1/urls") +async def read_urls(): + db = couch["urls"] + return [ { id: db[id].get('full_url') } for id in db ] + +@app.get("/api/v1/urls/{url_id}") +async def read_url(url_id, response: Response): + db = couch["urls"] + if url_id in db: + return db[url_id] + else: + response.status_code = 404 + return { "error": "Url not found" } + +# TODO: Throttle +# TODO: If user not found, generate a new JWT +@app.put("/api/v1/urls") +async def create_url(body: dict): + db = couch["urls"] + url_id = uuid.uuid4().hex[:6] + db[url_id] = { "full_url": body["url"], "user_id": body["username"] } + return + +@app.delete("/api/v1/urls/{url_id}") +async def delete_url(url_id, response: Response): + db = couch["urls"] + if url_id in db: + del db[url_id] + return { "message": "Url deleted" } + else: + response.status_code = 404 + return { "error": "Url not found" } diff --git a/api.restclient b/api.restclient new file mode 100644 index 0000000..298baf0 --- /dev/null +++ b/api.restclient @@ -0,0 +1,50 @@ +:headers = << +Content-Type: application/json +# +:host = http://localhost:8000 +:api = api/v1 + +# TODO: Check if urls should be singular or plural + +# Get all urls +GET :host/:api/urls +:headers + +# Get a url +GET :host/:api/urls/eecd98 + +# TODO: Change to POST +# Add a url +PUT :host/:api/urls +:headers +{ "username": "Joe" , "url": "https://ferano.io" } + +# Delete a url +DELETE :host/:api/urls/4485fe + +# Redirect +GET :host/eecd98 +:headers + + + +### +# Talk directly to CouchDB +### + +# Get value from key +GET http://admin:password@127.0.0.1:5984/urls/_all_docs?include_docs=true +:headers + +# Add a key/value pair +PUT http://admin:password@127.0.0.1:5984/urls/a28d530a +:headers +{ "user_id": "Joe", "full_url": "https://ferano.io" } + +# Delete a key/value pair +PUT http://admin:password@127.0.0.1:5984/urls +:headers + +# Delete a key/value pair +DELETE http://admin:password@127.0.0.1:5984/urls +:headers \ No newline at end of file diff --git a/client/index.html b/client/index.html new file mode 100644 index 0000000..d62891a --- /dev/null +++ b/client/index.html @@ -0,0 +1,16 @@ + + + + + + Zip My Link + + + +

Zip My Link

+

Type your long URL into the box and get a shorter URL back!

+ + +

+ + diff --git a/client/main.css b/client/main.css new file mode 100644 index 0000000..699a279 --- /dev/null +++ b/client/main.css @@ -0,0 +1,3 @@ +body { + margin: 0; +} diff --git a/client/main.js b/client/main.js new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6d1900d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +couchdb