In this post, I’ll show you how I set up a simple API using python’s FastAPI, with five GET endpoints. If you read my Creating an API with AWS series, you may recognise the endpoints. My eventual aim is to recreate the API I built in AWS using python.
Prerequisites
These are not strictly prerequisites, but you may find it useful to follow my series on Launching a CentOS7 Virtual Machine on Windows10, which will take you through the steps for setting up a CentOS7 virtual machine, with the end result being a virtual machine configured as an API server running FastAPI:
- Launching a CentOS7 Virtual Machine on Windows10
- Launching a CentOS7 Virtual Machine on Windows10: Part 2: Networking
- Launching a CentOS7 Virtual Machine on Windows10: Part 3: Shared Folder
- Launching a CentOS7 Virtual Machine on Windows10: Part 4: API Server
Step 1: Install FastAPI
See Launching a CentOS7 Virtual Machine on Windows10: Part 4: API Server for details on how to install FastAPI and configure a virtual environment to run the FastAPI server. The rest of this post will assume you have been able to get FastAPI running with the root endpoint which returns: {"message": "Hello World"}
.
Step 2: Add GET endpoints to main.py
Open main.py
and replace the code with the following:
from typing import Optional from fastapi import FastAPI, Query, Path, Body, HTTPException app = FastAPI() LINKS = [{'link_id': '1', 'link': 'https://google.com'}, {'link_id': '2', 'link': 'https://amazon.com'}] TAGS = [{'tag_id': '1', 'tag': 'search'}, {'tag_id': '2', 'tag': 'shop'}] TAG_LINKS = [{'link_id': '1', 'tag_id': '1'}, {'link_id': '2', 'tag_id': '2'}] def get_tag_id(tag: str): tag_id = None for tag_detail in TAGS: if tag_detail['tag'] == tag: tag_id = tag_detail['tag_id'] break return tag_id def fetch_tag(tag_id: str): for tag in TAGS: if tag['tag_id'] == tag_id: return tag return None # Get link by link_id @app.get("/link/{link_id}") async def get_link(link_id: str): for link in LINKS: if link['link_id'] == link_id: return link raise HTTPException(status_code=404, detail="Link not found") # Get links by query params @app.get("/link/") async def get_links(tag_id: Optional[str] = None, tag: Optional[str] = None): link_ids = [] return_links = [] if tag is None and tag_id is None: return LINKS if tag is not None: tag_id = get_tag_id(tag) if tag_id is not None: for tag_link in TAG_LINKS: if tag_link['tag_id'] == tag_id: link_ids.append(tag_link['link_id']) for link in LINKS: for link_id in link_ids: if link_id == link['link_id']: return_links.append(link) return return_links # Get tag by tag_id @app.get("/tag/{tag_id}") async def get_tag(tag_id: str): tag = fetch_tag(tag_id) if tag is not None: return tag raise HTTPException(status_code=404, detail=f"Tag with tag_id {tag_id} not found") # Get tags by query params @app.get("/tag/") async def get_tags(tag: Optional[str] = None): return_tags = [] if tag is None: return TAGS else: for tag_detail in TAGS: if tag_detail['tag'] == tag: return_tags.append(tag_detail) return return_tags # Get taglinks by query params @app.get("/taglink/") async def get_taglinks(link_id: Optional[str] = None, tag_id: Optional[str] = None): return_taglinks = [] if link_id is None and tag_id is None: return TAG_LINKS elif link_id is not None and tag_id is not None: for tag_link in TAG_LINKS: if tag_link['link_id'] == link_id and tag_link['tag_id'] == tag_id: return_taglinks.append(tag_link) elif link_id is not None: for tag_link in TAG_LINKS: if tag_link['link_id'] == link_id: return_taglinks.append(tag_link) else: # tag_id is not None for tag_link in TAG_LINKS: if tag_link['tag_id'] == tag_id: return_taglinks.append(tag_link) return return_taglinks
Step 3: Start FastAPI
Start the uvicorn API server, setting host to 0.0.0.0.0 so it will listen on any available interface:
$ uvicorn --host 0.0.0.0 main:app --reload
Step 4: Test FastAPI
-
With the API server running, navigate to
http://YOUR_IP:8000/docs
in your browser, replacingYOUR_IP
with either the IP set up in Launching a CentOS7 Virtual Machine on Windows10: Part 2: Networking, the IP of the virtual machine/server running FastAPI, or 127.0.0.1 if running FastAPI on your local machine. - You should see the swagger documentation for the GET endpoints. If you click on them in turn, then click ‘Try it out’, then enter parameter values in the form fields, then click ‘Execute’, you should see the response in the ‘Response Body’ box.
- Start a new PuTTY SSH session to your virtual machine/FastAPI server (if not running locally).
-
Try running:
curl -X 'GET' 'http://YOUR_IP:8000/link/' -H 'accept: application/json'
You should get the response:[ { "link_id": "1", "link": "https://google.com" }, { "link_id": "2", "link": "https://amazon.com" } ]
-
Try running:
curl -X 'GET' 'http://YOUR_IP:8000/tag/' -H 'accept: application/json'
You should get the response:[ { "tag_id": "1", "tag": "search" }, { "tag_id": "2", "tag": "shop" } ]
-
Try running:
curl -X 'GET' 'http://YOUR_IP:8000/taglink/' -H 'accept: application/json'
You should get the response:[ { "link_id": "1", "tag_id": "1" }, { "link_id": "2", "tag_id": "2" } ]
-
Try running:
curl -X 'GET' 'http://YOUR_IP:8000/link/1' -H 'accept: application/json'
You should get the response:{ "link_id": "1", "link": "https://google.com" }
-
Try running:
curl -X 'GET' 'http://YOUR_IP:8000/tag/1' -H 'accept: application/json'
You should get the response:{ "tag_id": "1", "tag": "search" }
Conclusion
You should now have a FastAPI API running with five GET endpoints, that can be called via a swagger (docs) page or via curl.
If you want to find out how to add a MariaDB database backend to the API, see my follow-on post, Creating an API with python: Part 2: MariaDB Database.
Thanks for reading!
2 Responses
[…] Creating an API with python: Part 1: GET Endpoints April 22, 2022 […]
[…] Creating an API with python: Part 1: GET Endpoints – All The Coding on Launching a CentOS7 Virtual Machine on Windows10 […]