Initial commit. API already works
This commit is contained in:
commit
78848e062f
1
.dir-locals.el
Normal file
1
.dir-locals.el
Normal file
@ -0,0 +1 @@
|
|||||||
|
((nil . ((eval . (set-frame-name "Zip My Link")))))
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
venv
|
||||||
|
__pycache__
|
48
api.py
Normal file
48
api.py
Normal file
@ -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" }
|
50
api.restclient
Normal file
50
api.restclient
Normal file
@ -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
|
16
client/index.html
Normal file
16
client/index.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Zip My Link</title>
|
||||||
|
<link rel="stylesheet" href="main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Zip My Link</h1>
|
||||||
|
<p>Type your long URL into the box and get a shorter URL back!</p>
|
||||||
|
<input type="text" id="url-input" placeholder="Enter your URL here">
|
||||||
|
<button onclick="submitUrl()">Shorten Url</button>
|
||||||
|
<p id="result"></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
3
client/main.css
Normal file
3
client/main.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
0
client/main.js
Normal file
0
client/main.js
Normal file
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
couchdb
|
Loading…
x
Reference in New Issue
Block a user