-
Notifications
You must be signed in to change notification settings - Fork 1
COVID 19 API
-
Story: A model in the database. It is a model for user's stories that they post in our app. Its fields are:
- id: Story's id to be kept in the database.
- title: Story's title with maximum char length 200
- story: Story's content with maximum char length 1000
- name: The user's name who posted the story. It has a maximum char length of 200.
- longitude: Story's location's longitude.
- latitude: Story's location's latitude.
- location: Story's location name with maximum char length 200.
- tag: Story's tag with maximum char length 200.
- date: Story's post date.
- notifyAdmin: Shows if a story needs to notify the admin or not.
- GeoDB Cities API: This API is used to get the country of a location.
- COVID-19 API: This API is used to get a country's covid-19 information for the day that request has been sent.
- COVID_API_KEY: A key to send requests to the third-party COVID-19 API.
The API that I have implemented first gets the story with the given ID, it is a valid ID. Then with the story's longitude and latitude, it sends a request to third-party API (GeoDB Cities API) with an API key taken from .env file. From the returned information it extracts the country of the specified story and it sends another request to a third=party API (COVID-19 API). From COVID-19 API's returned information it extracts the daily new corona cases, daily new corona deaths, and total active corona cases for the country which is found from the latter API.
- Get the daily coronavirus information of the country of the specified story.
Request:
GET
http://localhost:8000/api/covid/<story_id>
Parameters:
{
story_id = The id of the Story
}
Response:
{
"country": "X",
"day": X,
"new cases": X,
"new deaths": X,
"active cases": "X"
}
GET /api/covid/<valid story id>
{
"country": "Australia",
"day": "2021-06-10",
"new cases": "+15",
"new deaths": null,
"active cases": 159
}
GET /api/covid/<invalid story id (story with that id does not exist)>
Story object with story_id: X does not exist!
GET /api/covid/<valid story id> when COVID-19 API or GeoDB Cities API is not operational (either server is down or API key is invalid).
Could not establish a connection with API
To use COVID-19 API, there is no need for authentication. But since COVID-19 API uses API keys, there should be an API key to send a request to the API. It should be stored in .env file with the name COVID_API_KEY.
More information about the status codes can be found in https://httpstatuses.com/
Name | Meaning |
---|---|
HTTP_200_OK | Successful Request |
HTTP_404_NOT_FOUND | Error when the story with that id does not exist |
HTTP_500_INTERNAL_SERVER_ERROR | Server encountered an unexpected condition that prevented it from fulfilling the request |
- Models Used in COVID-19 API
This API uses only the Story model.
class Story(models.Model):
title = models.CharField(max_length=200)
story = models.CharField(max_length=1000)
name = models.CharField(max_length=200)
longitude = models.FloatField()
latitude = models.FloatField()
location = models.CharField(max_length=200)
tag = models.CharField(max_length=200)
date = models.DateTimeField(auto_now_add=True)
notifyAdmin = models.BooleanField(default=False)
def __str__(self):
return self.title
- Views
@api_view(['GET'])
def get_covid_numbers(request, story_id):
"""
Takes a story_id as a parameter and makes a call to Covid API to get
the covid metrics for the location of the Story instance with given story_id.
Returns the country, current day, new Covid cases, new Covid deaths and total
active cases for that country in JSON format.
"""
# Get the story object
env = environ.Env()
environ.Env.read_env('.env')
COVID_API_KEY = env('COVID_API_KEY')
CITY_API_KEY = env('COVID_API_KEY')
try:
story = Story.objects.get(pk=story_id)
except Story.DoesNotExist:
return HttpResponseNotFound(f"Story object with story_id: {story_id} does not exist!")
# Get the covid cases from Covid Api
try:
url = "https://wft-geo-db.p.rapidapi.com/v1/geo/cities"
locationinISOform=true_location_from(story.latitude, story.longitude)
querystring = {"location":locationinISOform,"radius":"100", "minPopulation":"10" }
headers = {
'x-rapidapi-key': CITY_API_KEY,
'x-rapidapi-host': "wft-geo-db.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers, params=querystring)
querystring = {"country":response.json()["data"][0]["country"]}
except:
return HttpResponseServerError("Could not establish connection with API")
try:
url = "https://covid-193.p.rapidapi.com/statistics"
headers = {
'x-rapidapi-key': COVID_API_KEY,
'x-rapidapi-host': "covid-193.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers, params=querystring)
json_data = json.loads(response.text)
except:
return HttpResponseServerError("Could not establish connection with Covid API")
try:
final_data = {
"country": json_data["parameters"]["country"],
"day": json_data["response"][0]["day"],
"new cases": json_data["response"][0]["cases"]["new"],
"new deaths": json_data["response"][0]["deaths"]["new"],
"active cases": json_data["response"][0]["cases"]["active"],
}
return JsonResponse(final_data)
except:
return HttpResponseServerError("No data available.", status= 404)
- Tests
class TestViews(TestCase):
def setUp(self):
"""
Sets up the common Client object to use it for GET responses.
Also creates the URLs and the Story objects to use later to get responses and also
to make comparisons.
"""
self.client = Client()
self.url_valid = reverse('covid_numbers', args=[1])
self.url_not_exists = reverse('covid_numbers', args=[5])
self.url_invalid = reverse('covid_numbers', args=[2])
self.post_valid = Story.objects.create(
id = 1,
title = 'TestTitle',
story = 'TestStory',
name = 'TestName',
longitude = 30.0,
latitude = 40.0,
location = 'Turkey',
tag = 'TestTag'
)
self.post_invalid = Story.objects.create(
id = 2,
title = 'TestTitle',
story = 'TestStory',
name = 'TestName',
longitude = 1.0,
latitude = 1.0,
location = 'Country Not Exists',
tag = 'TestTag'
)
def test_get_covid_numbers_success(self):
"""
Working test case, URL is as it should be
"""
response = self.client.get(self.url_valid)
self.assertEquals(response.status_code, 200)
def test_get_covid_numbers_id_not_exists(self):
"""
Test case for the URL maps to non existing Story instance
"""
response = self.client.get(self.url_not_exists)
self.assertEquals(response.status_code, 404)
def test_get_covid_numbers_response_fails(self):
"""
Requests with an invalid country to Covid-19 API
"""
response = self.client.get(self.url_invalid)
self.assertEquals(response.status_code, 500)
🏠 Home
👪 Team Members
- Milestone Reports
- Project Plans
- Project Selection
- Requirements
- Questions to Customer
- Scenarios and Mockups
- Design
- Meeting 1 (26.03.2021)
- Meeting 2 (01.04.2021)
- Meeting 3 (04.04.2021)
- Meeting 4 (07.04.2021)
- Customer Meeting 1 (14.04.2021)
- Meeting 5 (15.04.2021)
- Meeting 6 (17.04.2021)
- Meeting 7 (21.04.2021)
- Meeting 8 (25.04.2021)
- Meeting 9 (28.04.2021)
- Meeting 10 (03.05.2021)
- Meeting 11 (06.05.2021)
- Meeting 12 (07.05.2021)
- Meeting 13 (22.05.2021)
- Meeting 14 (26.05.2021)
- Meeting 15 (01.06.2021)
- Meeting 16 (04.06.2021)
- Meeting 17 (07.06.2021)
- Meeting 18 (08.06.2021)
- Meeting 19 (09.06.2021)
- Meeting 20 (12.06.2021)
- Lab 1 (12.10.2021)
- Meeting 1 (15.10.2021)
- Lab 2 (19.10.2021)
- Meeting 2 (25.10.2021)
- Lab 3 (26.10.2021)
- Meeting 3 (31.10.2021)
- Lab 4 (02.11.2021)
- Meeting 4 (08.11.2021)
- Lab 5 (09.11.2021)
- Meeting 5 (15.11.2021)
- Meeting 6 (18.11.2021)
- Lab 6 (23.11.2021)
- Lab 7 (30.11.2021)
- Lab 8 (21.12.2021)
- Lab 9 (28.12.2021)