Model APIs

Lesson 9 of 16

Lesson ยท 14 min

When a call fails

A call can fail

A model service runs on the computers of another company, and your program reaches it through a network. A call can fail for a reason that your code did not cause. A program that makes many calls gets each of these errors at some time.

Error in this course Cause Status code of a real service Does a new try help?
AuthError The key is missing or wrong. 401 No. Correct the key.
BadRequestError The call is wrong: the messages have a wrong form, the model does not exist, or the text is too long. 400 No. Correct the code.
RateLimitError You sent too many calls or too many tokens in a short time. 429 Yes, after a wait.
ServerError The service has a problem, or it has too much work. 500 or 503 Yes, after a wait.
ModelTimeout The answer did not come in time. None. Your program stopped the wait. Yes.

A real service answers each call with a status code, which is a number. The Python package of a service changes the status code into an error class. The names of the classes are different from service to service. The five groups are the same.

Two groups of errors

The last column of the table is the important one.

  • A new try can help. The cause is temporary. The same call can work some seconds later.
  • A new try cannot help. The call itself is wrong. It fails each time, until you change the key or the code.

A program that tries a wrong call again and again loses time, and it can reach the rate limit. A program that stops after one ServerError fails without need.

Catch the errors

Each error in Python has a class. The class is the name that you see in an error message, such as ValueError. The module sim_model has its own classes for the errors of the service.

Use try and except, as in lesson 8 of the course Python for data.

try:
    response = client.chat(messages)
except RateLimitError as error:
    print("Wait for", error.retry_after, "seconds.")
except ModelError as error:
    print(type(error).__name__, str(error))
  • as error gives the error a name, so that the block can read it.
  • ModelError is the parent class of the five errors. except ModelError catches each of them.
  • Python uses the first except block that fits. So put a special class before its parent class.
  • type(error).__name__ is the name of the class of the error, such as "ServerError".
  • str(error) is the text of the error.
  • A RateLimitError has the attribute retry_after. It is the number of seconds that the service asks you to wait.

Do not write except: without a class. It also catches a NameError from a typing mistake in your code, and then you do not see the mistake.

Errors on demand

The function plan of lesson 8 can also make a call fail.

Step What the call does
"rate_limit" It raises a RateLimitError.
"server_error" It raises a ServerError.
"timeout" It raises a ModelTimeout.

The simulated service raises an AuthError for a key that does not start with test-key. It raises a BadRequestError for a wrong call, such as an empty list of messages.

Your turn

main.py imports the error classes. Do the tasks in order.

Tasks

4 to do

  1. Task 1, not checked yet. Write a function can_retry(error). It returns True when the error is a RateLimitError, a ServerError or a ModelTimeout. For each other error, it returns False.

  2. Task 2, not checked yet. Write a function try_chat(messages). It calls client.chat(messages) in a try block. When the call works, it returns {"ok": True, "content": ...} with the text of the answer. When the call raises a ModelError, it returns {"ok": False, "error": ..., "retry": ...} with the name of the class of the error, and the result of can_retry.

  3. Task 3, not checked yet. Add the line plan(["server_error", "ok"]). It tells the simulated service to fail one time and then to answer. After that line, call try_chat(messages) two times. Store the results in first and second. Then store the result of try_chat([]) in bad. Print the three results.

  4. Task 4, not checked yet. Make a second client with a wrong key: guest = Client(api_key="guest"). Call guest.chat(messages) in a try block. Catch the AuthError, and store the text of the error in a variable auth_message.

Task 1 of 4

Write a function can_retry(error). It returns True when the error is a RateLimitError, a ServerError or a ModelTimeout. For each other error, it returns False.

All tasks

Ctrl+Enter runs your code. Ctrl+Shift+Enter checks it. Press Esc, then Tab, to leave the editor.

Output

Press Run to see your result

Your output shows here. Press Run to try your code.