Skip to content

COVID 19 API

Ahmet Şentürk edited this page Jun 13, 2021 · 1 revision

1. Glossary

  • 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.

2. Description

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.

3. Functionality

  • 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"
}

4. Example Responses

  • 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

5. Authentication

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.

6. Errors and Successes

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

7. Code Documenation

  • 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

💬 Communication

📈 Effort Tracking

🌐 Postory

🤸‍♀️ Practice App

📆 Project Plans & Milestone Reports

💻 Project Documentation

📝 Regular Meeting Reports

CMPE 352 Meetings

CMPE 451 Meetings

Android Meetings

Backend Meetings

Frontend Meetings

🔍 Research

📎 Templates

Clone this wiki locally