Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Create a management command to count API requests, create/update ApiBlock records, and send notifications #1139

Closed
jwalgran opened this issue Oct 16, 2020 · 1 comment
Assignees
Milestone

Comments

@jwalgran
Copy link
Contributor

jwalgran commented Oct 16, 2020

Overview

Create a management command to:

  • Count API requests
  • Create/update ApiBlock records
  • Send notification emails about changes to ApiBlock records

Describe the solution you'd like

Use unit tests to verify the multiple logic branches

The OAR moderation team will create the text for the email notifications.

NOTE: Make sure to use transactions where appropriate so that running this command multiple times concurrently will not result in an invalid state.

  • Add API_FREE_REQUEST_LIMIT to settings.py with a value of 50.
  • Add NOTIFICATION_EMAIL_TO to settings.py. Read the value from the NOTIFICATION_EMAIL_TO environment variable.
  • Add a placeholder value of notification@example.com for the NOTIFICATION_EMAIL_TO environment variable in docker-compose.yml
  • Create a check_api_limits management command with no arguments
  • Put the logic of the command in a testable check_api_limits(at_datetime) function
    • Management command calls this function passing UTC now as at_datetime
  • Add a ContributorNotifications model
    • Non-null OneToOneField to Contributor
    • api_limit_warning_sent_on - nullable datetime
    • api_limit_exceeded_sent_on - nullable datetime
    • api_grace_limit_exceeded_sent_on - nullable datetime
  • check_api_limits logic:
    • Count the RequestLog records with a status code between 200 and 299 created during the month at_datetime is within grouped by Contributor
    • For each Contributor that made requests`
      • Get or create a ContributorNotifications instance.
      • Get the request limit by checking if there is an ApiLimit record for the Contributor
        • If there is no limit, use the API_FREE_REQUEST_LIMIT from settings
      • The the limit is zero, do nothing. Zero represents unlimited usage.
      • If the count is over 90% of the limit but less than the limit, and ContributorNotifications.api_limit_warning_sent_on is null or in a previous month.
        • Send a user-facing notification email to the Contributor.admin
          • If the email is sent successfully, update ContributorNotifications.api_limit_warning_sent_on to the current time
        • Send an admin-facing notification email to the NOTIFICATION_EMAIL_TO address
      • If the count is over the limit
        • Check if there is an existing, ApiBlock for the Contributor where at_datetime is less than or equal to ApiBlock.until. There may be multiple blocks so sort by until descending and look at the first block.
        • If there is an existing block
          • If the block is active, do nothing.
          • If the block is not active and grace_limit is non null, compare the count
            • If the count is less than grace_limit do nothing
            • If the count is greater than grace_limit
              • Set active to true
              • Send a user-facing notification email to the Contributor.admin
                • If the email is sent successfully, update ContributorNotifications.api_grace_limit_exceeded_sent_on to the current time
              • Send an admin-facing notification email to the NOTIFICATION_EMAIL_TO address
        • If there is not an existing block
          • Create an active block with until set to the first day of the next month minus 1 second UTC
          • ContributorNotifications.api_limit_exceeded_sent_on is null or in a previous month.
            • Send a user-facing notification email to the Contributor.admin
              • If the email is sent successfully, update ContributorNotifications.api_limit_exceeded_sent_on to the current time
            • Send an admin-facing notification email to the NOTIFICATION_EMAIL_TO address
@jwalgran
Copy link
Contributor Author

@TaiWilkin I updated the description with a feature that I realized was omitted during our initial design meeting. We intend to run the check_api_limits management command on a schedule. If we send an email notification, we need to record that it was sent so that we don't keep sending repeat notifications every time we run check_api_limits.

My solution was to add a ContributorNotifications table with nullable date fields for each type of notification. Please let me know if you can think of another way of implementing this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants