nan-li / image-repository-api

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Image Repository API

This backend-focused project stores images hosted in Cloudinary and uses JSON Web Tokens for authorization.

You can make requests to the deployed server: http://54.80.94.139/

Content

  • I began by creating a Flask app and implementing a basic frontend using Jinja templates and vanilla JS/jQuery so that login and image uploading are simplified, but this is something I am already very comfortable doing.
  • Instead, I wondered about how to create an API that doesn't require a frontend where all requests can be done via Postman, for example. I realized I had no idea how to work without user forms in the browser.
  • After doing research, I read about HTTP Basic Auth and JSON Web Tokens (JWT), concepts unfamiliar to me, and this assignment grew into an opportunity to learn something new.
  • After testing my routes using Postman, I became intrigued to try everything from the command line and learned how to use cURL to do so.
  • Python
  • Flask
  • PostgreSQL
  • SQLAlchemy ORM
  • JSON Web Tokens
  • Cloudinary API

Instructions below on how to make requests to the listed routes from the command line using curl.

Register a new user account by providing the desired username and password in JSON format.

Making a request:

$ curl \
-d '{"username":"{YOUR_USERNAME}", "password":"{YOUR_PASSWORD}"}' \
-H 'Content-Type: application/json' \
http://54.80.94.139/users/register

Example:

$ curl \
-d '{"username":"user1", "password":"test1"}' \
-H 'Content-Type: application/json' \
http://54.80.94.139/users/register

Successful response:

{
  "message": "Account successfully created.", 
  "status": "success", 
  "user_id": "YOUR_USER_ID", 
  "username": "YOUR_USERNAME"
}

Login to user account by supplying username and password in JSON format. The response returns a token that will be needed to make subsequent API calls to protected routes.

Making a request:

$ curl \
-d '{"username":"{YOUR_USERNAME}", "password":"{YOUR_PASSWORD}"}' \
-H 'Content-Type: application/json' \
http://54.80.94.139/users/login

Example:

$ curl \
-d '{"username":"user1", "password":"test1"}' \
-H 'Content-Type: application/json' \
http://54.80.94.139/users/login

Successful response:

{
  "token": "{YOUR_TOKEN_HERE_AND_BE_SURE_TO_SAVE_IT}", 
  "user_id": "{YOUR_USER_ID}"
} 

The token returned from this route is long and can be tedious to include in subsequent requests. One suggestion is to store the token in the shell environment.

Save the token to shell environment:

$ export TOKEN="{COPY_THE_RETURNED_TOKEN}"

Verify the TOKEN variable with:

$ echo $TOKEN

Upload an image file by supplying the path to the file. Include your token in the request and supply your username in the route.

Making a request:

$ curl \
-F "image=@{PATH/TO/IMAGE.PNG}" \
-H "Authorization: Bearer {YOUR_TOKEN}" \
http://54.80.94.139/users/{YOUR_USERNAME}/upload

Example (uploading bear.png in the present directory):

Long way:

$ curl \
-F "image=@./bear.png" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTYyMDYwODY0NCwianRpIjoiOTQ4ZTAzZjgtMGRlNC00ODhhLWE0MzYtZmQ5NGJhNjY5ZWU4IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6MywibmJmIjoxNjIwNjA4NjQ0LCJleHAijE2MjA2MDk1NDR9.0lPlJGHwNk6MrEPpCvE5WZIGEmikJM0-l2PgxuqjDB8" \
http://54.80.94.139/users/user1/upload

Using $TOKEN env variable (double-quotes needed):

$ curl \
-F "image=@./bear.png" \
-H "Authorization: Bearer ${TOKEN}" \
http://54.80.94.139/users/user1/upload

By default, the permission on uploaded photos is set to PRIVATE. Set the permission of photo on upload to PUBLIC by adding '-F permission=PUBLIC'.

$ curl \
-F "image=@{PATH/TO/IMAGE.PNG}" \
-F permission=PUBLIC \
-H "Authorization: Bearer {YOUR_TOKEN}"  \
http://54.80.94.139/users/{YOUR_USERNAME}/upload

Successful response:

{
  "image_url": "{HTTP_URL_FOR_IMAGE}", 
  "message": "Image successfully uploaded.", 
  "permission": "{PRIVATE_OR_PUBLIC}", 
  "status": "success"
}

Returns all images if you are requesting your own images. Returns only public images of another user.

Making a request:

$ curl \
-H "Authorization: Bearer {YOUR_TOKEN}" \
http://54.80.94.139/users/{USERNAME}/images

Example:

$ curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTYyMDYwODY0NCwianRpIjoiOTQ4ZTAzZjgtMGRlNC00ODhhLWE0MzYtZmQ5NGJhNjY5ZWU4IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6MywibmJmIjoxNjIwNjA4NjQ0LCJleHAiOjE2jA2MDk1NDR9.0lPlJGHwNk6MrEPpCvE5WZIGEmikJM0-l2PgxuqjDB8" \
http://54.80.94.139/users/user1/images
$ curl -H "Authorization: Bearer ${TOKEN}" \
http://54.80.94.139/users/user1/images

Successful response:

{
  "images": [
    {
      "id": 1, 
      "image_url": "url/for/user1image1", 
      "permission": "PRIVATE"
    }, 
    {
      "id": 2, 
      "image_url": "url/for/user1image2_public", 
      "permission": "PUBLIC"
    }, 
    {
      "id": 4, 
      "image_url": "url/for/img", 
      "permission": "PUBLIC"
    }
  ], 
  "status": "success", 
  "total": 3
}
  • Clone this repository
$ git clone https://github.com/nan-li/image-repository-api.git
  • Create and activate a virtual environment in the directory
$ virtualenv env  
$ source env/bin/activate
  • Install dependencies
$ pip3 install -r requirements.txt
  • Sign up for a Cloudinary account
  • Create secrets.sh in the directory with the following:
export CLOUDINARY_CLOUD_NAME="YOUR_CLOUD_NAME"
export CLOUDINARY_API_KEY="YOUR_API_KEY"
export CLOUDINARY_API_SECRET="YOUR_API_SECRET"
export JWT_SECRET_KEY="YOUR_JWT_KEY"
  • Load these variables into the shell
$ source secrets.sh
  • Create and seed the database
$ python3 seed.py
  • Run the server
$ python3 server.py

Now you can make requests to your own server at: http://0.0.0.0:5000/

$ createdb testdb
$ python3 tests.py

About


Languages

Language:Python 100.0%