prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Update /availability API to pull from new registry
  ### Issue Description
  
  The [current API](https://github.com/cisagov/getgov/blob/784cc0f618e056c262512d688e8e4316dd25c9e4/src/api/views.py#L14) consists of a second-hand pull of canonical data that the .gov program [publishes to GitHub](https://github.com/cisagov/dotgov-data/blob/main/current-full.csv). Change this implementation so that queries poll the new registry/Whois/RDAP.
  
  ### Acceptance Criteria
  
  - [x] The checkDomain method is used to check that a domain is in the registry or not
  
  and
  
  - [x] The check is used at /availability 
  - [x] Tests are implemented and/or updated
  - [ ]  In the new domain application flow, where a user is checking if a domain is available for use, it should now use this /availability endpoint (if not already) and tests should be updated to check that /availability and epp is being triggered on this page as well. 
  
  ### Additional Context (optional)
  
  Once done, the backend work of #476 and frontend work of #561 can be completed.
  
  _Consider add-on to defend the endpoint from bot spam._
  
  ### Implementation Notes
  
  Epp has a check command that can be run with just the name of a given domain.  This should be used as the method for checking the desired domain at this endpoint.
  
  ### Issue Links
  
  Blocking #476 and #561
  Blocked by #1028 
  
  </issue>
  <code>
  [start of src/api/views.py]
  1 """Internal API views"""
  2 from django.apps import apps
  3 from django.views.decorators.http import require_http_methods
  4 from django.http import JsonResponse
  5 
  6 from django.contrib.auth.decorators import login_required
  7 
  8 import requests
  9 
  10 from cachetools.func import ttl_cache
  11 
  12 
  13 DOMAIN_FILE_URL = (
  14     "https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv"
  15 )
  16 
  17 
  18 DOMAIN_API_MESSAGES = {
  19     "required": "Enter the .gov domain you want. Don’t include “www” or “.gov.”"
  20     " For example, if you want www.city.gov, you would enter “city”"
  21     " (without the quotes).",
  22     "extra_dots": "Enter the .gov domain you want without any periods.",
  23     "unavailable": "That domain isn’t available. Try entering another one."
  24     " Contact us if you need help coming up with a domain.",
  25     "invalid": "Enter a domain using only letters,"
  26     " numbers, or hyphens (though we don't recommend using hyphens).",
  27     "success": "That domain is available!",
  28 }
  29 
  30 
  31 # this file doesn't change that often, nor is it that big, so cache the result
  32 # in memory for ten minutes
  33 @ttl_cache(ttl=600)
  34 def _domains():
  35     """Return a list of the current .gov domains.
  36 
  37     Fetch a file from DOMAIN_FILE_URL, parse the CSV for the domain,
  38     lowercase everything and return the list.
  39     """
  40     DraftDomain = apps.get_model("registrar.DraftDomain")
  41     # 5 second timeout
  42     file_contents = requests.get(DOMAIN_FILE_URL, timeout=5).text
  43     domains = set()
  44     # skip the first line
  45     for line in file_contents.splitlines()[1:]:
  46         # get the domain before the first comma
  47         domain = line.split(",", 1)[0]
  48         # sanity-check the string we got from the file here
  49         if DraftDomain.string_could_be_domain(domain):
  50             # lowercase everything when we put it in domains
  51             domains.add(domain.lower())
  52     return domains
  53 
  54 
  55 def in_domains(domain):
  56     """Return true if the given domain is in the domains list.
  57 
  58     The given domain is lowercased to match against the domains list. If the
  59     given domain doesn't end with .gov, ".gov" is added when looking for
  60     a match.
  61     """
  62     domain = domain.lower()
  63     if domain.endswith(".gov"):
  64         return domain.lower() in _domains()
  65     else:
  66         # domain search string doesn't end with .gov, add it on here
  67         return (domain + ".gov") in _domains()
  68 
  69 
  70 @require_http_methods(["GET"])
  71 @login_required
  72 def available(request, domain=""):
  73     """Is a given domain available or not.
  74 
  75     Response is a JSON dictionary with the key "available" and value true or
  76     false.
  77     """
  78     DraftDomain = apps.get_model("registrar.DraftDomain")
  79     # validate that the given domain could be a domain name and fail early if
  80     # not.
  81     if not (
  82         DraftDomain.string_could_be_domain(domain)
  83         or DraftDomain.string_could_be_domain(domain + ".gov")
  84     ):
  85         return JsonResponse(
  86             {"available": False, "message": DOMAIN_API_MESSAGES["invalid"]}
  87         )
  88     # a domain is available if it is NOT in the list of current domains
  89     if in_domains(domain):
  90         return JsonResponse(
  91             {"available": False, "message": DOMAIN_API_MESSAGES["unavailable"]}
  92         )
  93     else:
  94         return JsonResponse(
  95             {"available": True, "message": DOMAIN_API_MESSAGES["success"]}
  96         )
  97
  [end of src/api/views.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/api/views.py b/src/api/views.py
  --- a/src/api/views.py
  +++ b/src/api/views.py
  @@ -59,12 +59,12 @@
       given domain doesn't end with .gov, ".gov" is added when looking for
       a match.
       """
  -    domain = domain.lower()
  +    Domain = apps.get_model("registrar.Domain")
       if domain.endswith(".gov"):
  -        return domain.lower() in _domains()
  +        return Domain.available(domain)
       else:
           # domain search string doesn't end with .gov, add it on here
  -        return (domain + ".gov") in _domains()
  +        return Domain.available(domain + ".gov")
   
   
   @require_http_methods(["GET"])
  
verification_info: {"golden_diff": "diff --git a/src/api/views.py b/src/api/views.py\n--- a/src/api/views.py\n+++ b/src/api/views.py\n@@ -59,12 +59,12 @@\n     given domain doesn't end with .gov, \".gov\" is added when looking for\n     a match.\n     \"\"\"\n-    domain = domain.lower()\n+    Domain = apps.get_model(\"registrar.Domain\")\n     if domain.endswith(\".gov\"):\n-        return domain.lower() in _domains()\n+        return Domain.available(domain)\n     else:\n         # domain search string doesn't end with .gov, add it on here\n-        return (domain + \".gov\") in _domains()\n+        return Domain.available(domain + \".gov\")\n \n \n @require_http_methods([\"GET\"])\n", "issue": "Update /availability API to pull from new registry\n### Issue Description\r\n\r\nThe [current API](https://github.com/cisagov/getgov/blob/784cc0f618e056c262512d688e8e4316dd25c9e4/src/api/views.py#L14) consists of a second-hand pull of canonical data that the .gov program [publishes to GitHub](https://github.com/cisagov/dotgov-data/blob/main/current-full.csv). Change this implementation so that queries poll the new registry/Whois/RDAP.\r\n\r\n### Acceptance Criteria\r\n\r\n- [x] The checkDomain method is used to check that a domain is in the registry or not\r\n\r\nand\r\n\r\n- [x] The check is used at /availability \r\n- [x] Tests are implemented and/or updated\r\n- [ ]  In the new domain application flow, where a user is checking if a domain is available for use, it should now use this /availability endpoint (if not already) and tests should be updated to check that /availability and epp is being triggered on this page as well. \r\n\r\n### Additional Context (optional)\r\n\r\nOnce done, the backend work of #476 and frontend work of #561 can be completed.\r\n\r\n_Consider add-on to defend the endpoint from bot spam._\r\n\r\n### Implementation Notes\r\n\r\nEpp has a check command that can be run with just the name of a given domain.  This should be used as the method for checking the desired domain at this endpoint.\r\n\r\n### Issue Links\r\n\r\nBlocking #476 and #561\r\nBlocked by #1028 \n", "before_files": [{"content": "\"\"\"Internal API views\"\"\"\nfrom django.apps import apps\nfrom django.views.decorators.http import require_http_methods\nfrom django.http import JsonResponse\n\nfrom django.contrib.auth.decorators import login_required\n\nimport requests\n\nfrom cachetools.func import ttl_cache\n\n\nDOMAIN_FILE_URL = (\n    \"https://raw.githubusercontent.com/cisagov/dotgov-data/main/current-full.csv\"\n)\n\n\nDOMAIN_API_MESSAGES = {\n    \"required\": \"Enter the .gov domain you want. Don\u2019t include \u201cwww\u201d or \u201c.gov.\u201d\"\n    \" For example, if you want www.city.gov, you would enter \u201ccity\u201d\"\n    \" (without the quotes).\",\n    \"extra_dots\": \"Enter the .gov domain you want without any periods.\",\n    \"unavailable\": \"That domain isn\u2019t available. Try entering another one.\"\n    \" Contact us if you need help coming up with a domain.\",\n    \"invalid\": \"Enter a domain using only letters,\"\n    \" numbers, or hyphens (though we don't recommend using hyphens).\",\n    \"success\": \"That domain is available!\",\n}\n\n\n# this file doesn't change that often, nor is it that big, so cache the result\n# in memory for ten minutes\n@ttl_cache(ttl=600)\ndef _domains():\n    \"\"\"Return a list of the current .gov domains.\n\n    Fetch a file from DOMAIN_FILE_URL, parse the CSV for the domain,\n    lowercase everything and return the list.\n    \"\"\"\n    DraftDomain = apps.get_model(\"registrar.DraftDomain\")\n    # 5 second timeout\n    file_contents = requests.get(DOMAIN_FILE_URL, timeout=5).text\n    domains = set()\n    # skip the first line\n    for line in file_contents.splitlines()[1:]:\n        # get the domain before the first comma\n        domain = line.split(\",\", 1)[0]\n        # sanity-check the string we got from the file here\n        if DraftDomain.string_could_be_domain(domain):\n            # lowercase everything when we put it in domains\n            domains.add(domain.lower())\n    return domains\n\n\ndef in_domains(domain):\n    \"\"\"Return true if the given domain is in the domains list.\n\n    The given domain is lowercased to match against the domains list. If the\n    given domain doesn't end with .gov, \".gov\" is added when looking for\n    a match.\n    \"\"\"\n    domain = domain.lower()\n    if domain.endswith(\".gov\"):\n        return domain.lower() in _domains()\n    else:\n        # domain search string doesn't end with .gov, add it on here\n        return (domain + \".gov\") in _domains()\n\n\n@require_http_methods([\"GET\"])\n@login_required\ndef available(request, domain=\"\"):\n    \"\"\"Is a given domain available or not.\n\n    Response is a JSON dictionary with the key \"available\" and value true or\n    false.\n    \"\"\"\n    DraftDomain = apps.get_model(\"registrar.DraftDomain\")\n    # validate that the given domain could be a domain name and fail early if\n    # not.\n    if not (\n        DraftDomain.string_could_be_domain(domain)\n        or DraftDomain.string_could_be_domain(domain + \".gov\")\n    ):\n        return JsonResponse(\n            {\"available\": False, \"message\": DOMAIN_API_MESSAGES[\"invalid\"]}\n        )\n    # a domain is available if it is NOT in the list of current domains\n    if in_domains(domain):\n        return JsonResponse(\n            {\"available\": False, \"message\": DOMAIN_API_MESSAGES[\"unavailable\"]}\n        )\n    else:\n        return JsonResponse(\n            {\"available\": True, \"message\": DOMAIN_API_MESSAGES[\"success\"]}\n        )\n", "path": "src/api/views.py"}]}