We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Clean up code for hacky OpenAPI curl test
After testing `deactivate_own_account` endpoint, we need to reactivate the client so that other tests are not affected by the deactivated client. In `test_curl_examples`, this has been hackily implemented and should be replaced by cleaner code. More details at https://github.com/zulip/zulip/pull/17014#discussion_r601173277

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `zerver/openapi/curl_param_value_generators.py`
Content:
```
1 # Zulip's OpenAPI-based API documentation system is documented at
2 #   https://zulip.readthedocs.io/en/latest/documentation/api.html
3 #
4 # This file contains helper functions for generating cURL examples
5 # based on Zulip's OpenAPI definitions, as well as test setup and
6 # fetching of appropriate parameter values to use when running the
7 # cURL examples as part of the tools/test-api test suite.
8 from functools import wraps
9 from typing import Any, Callable, Dict, List, Optional, Set, Tuple
10 
11 from django.utils.timezone import now as timezone_now
12 
13 from zerver.lib.actions import (
14     do_add_linkifier,
15     do_add_reaction,
16     do_add_realm_playground,
17     do_create_user,
18     update_user_presence,
19 )
20 from zerver.lib.events import do_events_register
21 from zerver.lib.initial_password import initial_password
22 from zerver.lib.test_classes import ZulipTestCase
23 from zerver.models import Client, Message, UserGroup, UserPresence, get_realm
24 
25 GENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}
26 REGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()
27 CALLED_GENERATOR_FUNCTIONS: Set[str] = set()
28 
29 helpers = ZulipTestCase()
30 
31 
32 def openapi_param_value_generator(
33     endpoints: List[str],
34 ) -> Callable[[Callable[[], Dict[str, object]]], Callable[[], Dict[str, object]]]:
35     """This decorator is used to register OpenAPI param value genarator functions
36     with endpoints. Example usage:
37 
38     @openapi_param_value_generator(["/messages/render:post"])
39     def ...
40     """
41 
42     def wrapper(generator_func: Callable[[], Dict[str, object]]) -> Callable[[], Dict[str, object]]:
43         @wraps(generator_func)
44         def _record_calls_wrapper() -> Dict[str, object]:
45             CALLED_GENERATOR_FUNCTIONS.add(generator_func.__name__)
46             return generator_func()
47 
48         REGISTERED_GENERATOR_FUNCTIONS.add(generator_func.__name__)
49         for endpoint in endpoints:
50             GENERATOR_FUNCTIONS[endpoint] = _record_calls_wrapper
51 
52         return _record_calls_wrapper
53 
54     return wrapper
55 
56 
57 def assert_all_helper_functions_called() -> None:
58     """Throws an exception if any registered helpers were not called by tests"""
59     if REGISTERED_GENERATOR_FUNCTIONS == CALLED_GENERATOR_FUNCTIONS:
60         return
61 
62     uncalled_functions = str(REGISTERED_GENERATOR_FUNCTIONS - CALLED_GENERATOR_FUNCTIONS)
63 
64     raise Exception(f"Registered curl API generators were not called: {uncalled_functions}")
65 
66 
67 def patch_openapi_example_values(
68     entry: str,
69     params: List[Dict[str, Any]],
70     request_body: Optional[Dict[str, Any]] = None,
71 ) -> Tuple[List[Dict[str, object]], Optional[Dict[str, object]]]:
72     if entry not in GENERATOR_FUNCTIONS:
73         return params, request_body
74     func = GENERATOR_FUNCTIONS[entry]
75     realm_example_values: Dict[str, object] = func()
76 
77     for param in params:
78         param_name = param["name"]
79         if param_name in realm_example_values:
80             if "content" in param:
81                 param["content"]["application/json"]["example"] = realm_example_values[param_name]
82             else:
83                 param["example"] = realm_example_values[param_name]
84 
85     if request_body is not None:
86         properties = request_body["content"]["multipart/form-data"]["schema"]["properties"]
87         for key, property in properties.items():
88             if key in realm_example_values:
89                 property["example"] = realm_example_values[key]
90     return params, request_body
91 
92 
93 @openapi_param_value_generator(["/fetch_api_key:post"])
94 def fetch_api_key() -> Dict[str, object]:
95     email = helpers.example_email("iago")
96     password = initial_password(email)
97 
98     return {
99         "username": email,
100         "password": password,
101     }
102 
103 
104 @openapi_param_value_generator(
105     [
106         "/messages/{message_id}:get",
107         "/messages/{message_id}/history:get",
108         "/messages/{message_id}:patch",
109         "/messages/{message_id}:delete",
110     ]
111 )
112 def iago_message_id() -> Dict[str, object]:
113     return {
114         "message_id": helpers.send_stream_message(helpers.example_user("iago"), "Denmark"),
115     }
116 
117 
118 @openapi_param_value_generator(["/messages/{message_id}/reactions:delete"])
119 def add_emoji_to_message() -> Dict[str, object]:
120     user_profile = helpers.example_user("iago")
121 
122     # from OpenAPI format data in zulip.yaml
123     message_id = 41
124     emoji_name = "octopus"
125     emoji_code = "1f419"
126     reaction_type = "unicode_emoji"
127 
128     message = Message.objects.select_related().get(id=message_id)
129     do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)
130 
131     return {}
132 
133 
134 @openapi_param_value_generator(["/messages/flags:post"])
135 def update_flags_message_ids() -> Dict[str, object]:
136     stream_name = "Venice"
137     helpers.subscribe(helpers.example_user("iago"), stream_name)
138 
139     messages = []
140     for _ in range(3):
141         messages.append(helpers.send_stream_message(helpers.example_user("iago"), stream_name))
142     return {
143         "messages": messages,
144     }
145 
146 
147 @openapi_param_value_generator(["/mark_stream_as_read:post", "/users/me/{stream_id}/topics:get"])
148 def get_venice_stream_id() -> Dict[str, object]:
149     return {
150         "stream_id": helpers.get_stream_id("Venice"),
151     }
152 
153 
154 @openapi_param_value_generator(["/streams/{stream_id}:patch"])
155 def update_stream() -> Dict[str, object]:
156     stream = helpers.subscribe(helpers.example_user("iago"), "temp_stream 1")
157     return {
158         "stream_id": stream.id,
159     }
160 
161 
162 @openapi_param_value_generator(["/streams/{stream_id}:delete"])
163 def create_temp_stream_and_get_id() -> Dict[str, object]:
164     stream = helpers.subscribe(helpers.example_user("iago"), "temp_stream 2")
165     return {
166         "stream_id": stream.id,
167     }
168 
169 
170 @openapi_param_value_generator(["/mark_topic_as_read:post"])
171 def get_denmark_stream_id_and_topic() -> Dict[str, object]:
172     stream_name = "Denmark"
173     topic_name = "Tivoli Gardens"
174 
175     helpers.subscribe(helpers.example_user("iago"), stream_name)
176     helpers.send_stream_message(helpers.example_user("hamlet"), stream_name, topic_name=topic_name)
177 
178     return {
179         "stream_id": helpers.get_stream_id(stream_name),
180         "topic_name": topic_name,
181     }
182 
183 
184 @openapi_param_value_generator(["/users/me/subscriptions/properties:post"])
185 def update_subscription_data() -> Dict[str, object]:
186     profile = helpers.example_user("iago")
187     helpers.subscribe(profile, "Verona")
188     helpers.subscribe(profile, "social")
189     return {
190         "subscription_data": [
191             {"stream_id": helpers.get_stream_id("Verona"), "property": "pin_to_top", "value": True},
192             {"stream_id": helpers.get_stream_id("social"), "property": "color", "value": "#f00f00"},
193         ],
194     }
195 
196 
197 @openapi_param_value_generator(["/users/me/subscriptions:delete"])
198 def delete_subscription_data() -> Dict[str, object]:
199     iago = helpers.example_user("iago")
200     zoe = helpers.example_user("ZOE")
201     helpers.subscribe(iago, "Verona")
202     helpers.subscribe(iago, "social")
203     helpers.subscribe(zoe, "Verona")
204     helpers.subscribe(zoe, "social")
205     return {}
206 
207 
208 @openapi_param_value_generator(["/events:get"])
209 def get_events() -> Dict[str, object]:
210     profile = helpers.example_user("iago")
211     helpers.subscribe(profile, "Verona")
212     client = Client.objects.create(name="curl-test-client-1")
213     response = do_events_register(profile, client, event_types=["message", "realm_emoji"])
214     helpers.send_stream_message(helpers.example_user("hamlet"), "Verona")
215     return {
216         "queue_id": response["queue_id"],
217         "last_event_id": response["last_event_id"],
218     }
219 
220 
221 @openapi_param_value_generator(["/events:delete"])
222 def delete_event_queue() -> Dict[str, object]:
223     profile = helpers.example_user("iago")
224     client = Client.objects.create(name="curl-test-client-2")
225     response = do_events_register(profile, client, event_types=["message"])
226     return {
227         "queue_id": response["queue_id"],
228         "last_event_id": response["last_event_id"],
229     }
230 
231 
232 @openapi_param_value_generator(["/users/{user_id_or_email}/presence:get"])
233 def get_user_presence() -> Dict[str, object]:
234     iago = helpers.example_user("iago")
235     client = Client.objects.create(name="curl-test-client-3")
236     update_user_presence(iago, client, timezone_now(), UserPresence.ACTIVE, False)
237     return {}
238 
239 
240 @openapi_param_value_generator(["/users:post"])
241 def create_user() -> Dict[str, object]:
242     return {
243         "email": helpers.nonreg_email("test"),
244     }
245 
246 
247 @openapi_param_value_generator(["/user_groups/create:post"])
248 def create_user_group_data() -> Dict[str, object]:
249     return {
250         "members": [helpers.example_user("hamlet").id, helpers.example_user("othello").id],
251     }
252 
253 
254 @openapi_param_value_generator(
255     ["/user_groups/{user_group_id}:patch", "/user_groups/{user_group_id}:delete"]
256 )
257 def get_temp_user_group_id() -> Dict[str, object]:
258     user_group, _ = UserGroup.objects.get_or_create(name="temp", realm=get_realm("zulip"))
259     return {
260         "user_group_id": user_group.id,
261     }
262 
263 
264 @openapi_param_value_generator(["/realm/filters/{filter_id}:delete"])
265 def remove_realm_filters() -> Dict[str, object]:
266     filter_id = do_add_linkifier(
267         get_realm("zulip"), "#(?P<id>[0-9]{2,8})", "https://github.com/zulip/zulip/pull/%(id)s"
268     )
269     return {
270         "filter_id": filter_id,
271     }
272 
273 
274 @openapi_param_value_generator(["/realm/emoji/{emoji_name}:post", "/user_uploads:post"])
275 def upload_custom_emoji() -> Dict[str, object]:
276     return {
277         "filename": "zerver/tests/images/animated_img.gif",
278     }
279 
280 
281 @openapi_param_value_generator(["/realm/playgrounds:post"])
282 def add_realm_playground() -> Dict[str, object]:
283     return {
284         "name": "Python2 playground",
285         "pygments_language": "Python2",
286         "url_prefix": "https://python2.example.com",
287     }
288 
289 
290 @openapi_param_value_generator(["/realm/playgrounds/{playground_id}:delete"])
291 def remove_realm_playground() -> Dict[str, object]:
292     playground_info = dict(
293         name="Python playground",
294         pygments_language="Python",
295         url_prefix="https://python.example.com",
296     )
297     playground_id = do_add_realm_playground(get_realm("zulip"), **playground_info)
298     return {
299         "playground_id": playground_id,
300     }
301 
302 
303 @openapi_param_value_generator(["/users/{user_id}:delete"])
304 def deactivate_user() -> Dict[str, object]:
305     user_profile = do_create_user(
306         email="testuser@zulip.com",
307         password=None,
308         full_name="test_user",
309         realm=get_realm("zulip"),
310         acting_user=None,
311     )
312     return {"user_id": user_profile.id}
313
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/zerver/openapi/curl_param_value_generators.py b/zerver/openapi/curl_param_value_generators.py
--- a/zerver/openapi/curl_param_value_generators.py
+++ b/zerver/openapi/curl_param_value_generators.py
@@ -20,11 +20,15 @@
 from zerver.lib.events import do_events_register
 from zerver.lib.initial_password import initial_password
 from zerver.lib.test_classes import ZulipTestCase
-from zerver.models import Client, Message, UserGroup, UserPresence, get_realm
+from zerver.lib.users import get_api_key
+from zerver.models import Client, Message, UserGroup, UserPresence, get_realm, get_user
 
 GENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}
 REGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()
 CALLED_GENERATOR_FUNCTIONS: Set[str] = set()
+# This is a List rather than just a string in order to make it easier
+# to write to it from another module.
+AUTHENTICATION_LINE: List[str] = [""]
 
 helpers = ZulipTestCase()
 
@@ -310,3 +314,22 @@
         acting_user=None,
     )
     return {"user_id": user_profile.id}
+
+
+@openapi_param_value_generator(["/users/me:delete"])
+def deactivate_own_user() -> Dict[str, object]:
+    test_user_email = "delete-test@zulip.com"
+    deactivate_test_user = do_create_user(
+        test_user_email,
+        "secret",
+        get_realm("zulip"),
+        "Mr. Delete",
+        role=200,
+        acting_user=None,
+    )
+    realm = get_realm("zulip")
+    test_user = get_user(test_user_email, realm)
+    test_user_api_key = get_api_key(test_user)
+    # change authentication line to allow test_client to delete itself.
+    AUTHENTICATION_LINE[0] = f"{deactivate_test_user.email}:{test_user_api_key}"
+    return {}

{"golden_diff": "diff --git a/zerver/openapi/curl_param_value_generators.py b/zerver/openapi/curl_param_value_generators.py\n--- a/zerver/openapi/curl_param_value_generators.py\n+++ b/zerver/openapi/curl_param_value_generators.py\n@@ -20,11 +20,15 @@\n from zerver.lib.events import do_events_register\n from zerver.lib.initial_password import initial_password\n from zerver.lib.test_classes import ZulipTestCase\n-from zerver.models import Client, Message, UserGroup, UserPresence, get_realm\n+from zerver.lib.users import get_api_key\n+from zerver.models import Client, Message, UserGroup, UserPresence, get_realm, get_user\n \n GENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}\n REGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()\n CALLED_GENERATOR_FUNCTIONS: Set[str] = set()\n+# This is a List rather than just a string in order to make it easier\n+# to write to it from another module.\n+AUTHENTICATION_LINE: List[str] = [\"\"]\n \n helpers = ZulipTestCase()\n \n@@ -310,3 +314,22 @@\n         acting_user=None,\n     )\n     return {\"user_id\": user_profile.id}\n+\n+\n+@openapi_param_value_generator([\"/users/me:delete\"])\n+def deactivate_own_user() -> Dict[str, object]:\n+    test_user_email = \"delete-test@zulip.com\"\n+    deactivate_test_user = do_create_user(\n+        test_user_email,\n+        \"secret\",\n+        get_realm(\"zulip\"),\n+        \"Mr. Delete\",\n+        role=200,\n+        acting_user=None,\n+    )\n+    realm = get_realm(\"zulip\")\n+    test_user = get_user(test_user_email, realm)\n+    test_user_api_key = get_api_key(test_user)\n+    # change authentication line to allow test_client to delete itself.\n+    AUTHENTICATION_LINE[0] = f\"{deactivate_test_user.email}:{test_user_api_key}\"\n+    return {}\n", "issue": "Clean up code for hacky OpenAPI curl test\nAfter testing `deactivate_own_account` endpoint, we need to reactivate the client so that other tests are not affected by the deactivated client. In `test_curl_examples`, this has been hackily implemented and should be replaced by cleaner code. More details at https://github.com/zulip/zulip/pull/17014#discussion_r601173277\n", "before_files": [{"content": "# Zulip's OpenAPI-based API documentation system is documented at\n#   https://zulip.readthedocs.io/en/latest/documentation/api.html\n#\n# This file contains helper functions for generating cURL examples\n# based on Zulip's OpenAPI definitions, as well as test setup and\n# fetching of appropriate parameter values to use when running the\n# cURL examples as part of the tools/test-api test suite.\nfrom functools import wraps\nfrom typing import Any, Callable, Dict, List, Optional, Set, Tuple\n\nfrom django.utils.timezone import now as timezone_now\n\nfrom zerver.lib.actions import (\n    do_add_linkifier,\n    do_add_reaction,\n    do_add_realm_playground,\n    do_create_user,\n    update_user_presence,\n)\nfrom zerver.lib.events import do_events_register\nfrom zerver.lib.initial_password import initial_password\nfrom zerver.lib.test_classes import ZulipTestCase\nfrom zerver.models import Client, Message, UserGroup, UserPresence, get_realm\n\nGENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}\nREGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()\nCALLED_GENERATOR_FUNCTIONS: Set[str] = set()\n\nhelpers = ZulipTestCase()\n\n\ndef openapi_param_value_generator(\n    endpoints: List[str],\n) -> Callable[[Callable[[], Dict[str, object]]], Callable[[], Dict[str, object]]]:\n    \"\"\"This decorator is used to register OpenAPI param value genarator functions\n    with endpoints. Example usage:\n\n    @openapi_param_value_generator([\"/messages/render:post\"])\n    def ...\n    \"\"\"\n\n    def wrapper(generator_func: Callable[[], Dict[str, object]]) -> Callable[[], Dict[str, object]]:\n        @wraps(generator_func)\n        def _record_calls_wrapper() -> Dict[str, object]:\n            CALLED_GENERATOR_FUNCTIONS.add(generator_func.__name__)\n            return generator_func()\n\n        REGISTERED_GENERATOR_FUNCTIONS.add(generator_func.__name__)\n        for endpoint in endpoints:\n            GENERATOR_FUNCTIONS[endpoint] = _record_calls_wrapper\n\n        return _record_calls_wrapper\n\n    return wrapper\n\n\ndef assert_all_helper_functions_called() -> None:\n    \"\"\"Throws an exception if any registered helpers were not called by tests\"\"\"\n    if REGISTERED_GENERATOR_FUNCTIONS == CALLED_GENERATOR_FUNCTIONS:\n        return\n\n    uncalled_functions = str(REGISTERED_GENERATOR_FUNCTIONS - CALLED_GENERATOR_FUNCTIONS)\n\n    raise Exception(f\"Registered curl API generators were not called: {uncalled_functions}\")\n\n\ndef patch_openapi_example_values(\n    entry: str,\n    params: List[Dict[str, Any]],\n    request_body: Optional[Dict[str, Any]] = None,\n) -> Tuple[List[Dict[str, object]], Optional[Dict[str, object]]]:\n    if entry not in GENERATOR_FUNCTIONS:\n        return params, request_body\n    func = GENERATOR_FUNCTIONS[entry]\n    realm_example_values: Dict[str, object] = func()\n\n    for param in params:\n        param_name = param[\"name\"]\n        if param_name in realm_example_values:\n            if \"content\" in param:\n                param[\"content\"][\"application/json\"][\"example\"] = realm_example_values[param_name]\n            else:\n                param[\"example\"] = realm_example_values[param_name]\n\n    if request_body is not None:\n        properties = request_body[\"content\"][\"multipart/form-data\"][\"schema\"][\"properties\"]\n        for key, property in properties.items():\n            if key in realm_example_values:\n                property[\"example\"] = realm_example_values[key]\n    return params, request_body\n\n\n@openapi_param_value_generator([\"/fetch_api_key:post\"])\ndef fetch_api_key() -> Dict[str, object]:\n    email = helpers.example_email(\"iago\")\n    password = initial_password(email)\n\n    return {\n        \"username\": email,\n        \"password\": password,\n    }\n\n\n@openapi_param_value_generator(\n    [\n        \"/messages/{message_id}:get\",\n        \"/messages/{message_id}/history:get\",\n        \"/messages/{message_id}:patch\",\n        \"/messages/{message_id}:delete\",\n    ]\n)\ndef iago_message_id() -> Dict[str, object]:\n    return {\n        \"message_id\": helpers.send_stream_message(helpers.example_user(\"iago\"), \"Denmark\"),\n    }\n\n\n@openapi_param_value_generator([\"/messages/{message_id}/reactions:delete\"])\ndef add_emoji_to_message() -> Dict[str, object]:\n    user_profile = helpers.example_user(\"iago\")\n\n    # from OpenAPI format data in zulip.yaml\n    message_id = 41\n    emoji_name = \"octopus\"\n    emoji_code = \"1f419\"\n    reaction_type = \"unicode_emoji\"\n\n    message = Message.objects.select_related().get(id=message_id)\n    do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)\n\n    return {}\n\n\n@openapi_param_value_generator([\"/messages/flags:post\"])\ndef update_flags_message_ids() -> Dict[str, object]:\n    stream_name = \"Venice\"\n    helpers.subscribe(helpers.example_user(\"iago\"), stream_name)\n\n    messages = []\n    for _ in range(3):\n        messages.append(helpers.send_stream_message(helpers.example_user(\"iago\"), stream_name))\n    return {\n        \"messages\": messages,\n    }\n\n\n@openapi_param_value_generator([\"/mark_stream_as_read:post\", \"/users/me/{stream_id}/topics:get\"])\ndef get_venice_stream_id() -> Dict[str, object]:\n    return {\n        \"stream_id\": helpers.get_stream_id(\"Venice\"),\n    }\n\n\n@openapi_param_value_generator([\"/streams/{stream_id}:patch\"])\ndef update_stream() -> Dict[str, object]:\n    stream = helpers.subscribe(helpers.example_user(\"iago\"), \"temp_stream 1\")\n    return {\n        \"stream_id\": stream.id,\n    }\n\n\n@openapi_param_value_generator([\"/streams/{stream_id}:delete\"])\ndef create_temp_stream_and_get_id() -> Dict[str, object]:\n    stream = helpers.subscribe(helpers.example_user(\"iago\"), \"temp_stream 2\")\n    return {\n        \"stream_id\": stream.id,\n    }\n\n\n@openapi_param_value_generator([\"/mark_topic_as_read:post\"])\ndef get_denmark_stream_id_and_topic() -> Dict[str, object]:\n    stream_name = \"Denmark\"\n    topic_name = \"Tivoli Gardens\"\n\n    helpers.subscribe(helpers.example_user(\"iago\"), stream_name)\n    helpers.send_stream_message(helpers.example_user(\"hamlet\"), stream_name, topic_name=topic_name)\n\n    return {\n        \"stream_id\": helpers.get_stream_id(stream_name),\n        \"topic_name\": topic_name,\n    }\n\n\n@openapi_param_value_generator([\"/users/me/subscriptions/properties:post\"])\ndef update_subscription_data() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    helpers.subscribe(profile, \"Verona\")\n    helpers.subscribe(profile, \"social\")\n    return {\n        \"subscription_data\": [\n            {\"stream_id\": helpers.get_stream_id(\"Verona\"), \"property\": \"pin_to_top\", \"value\": True},\n            {\"stream_id\": helpers.get_stream_id(\"social\"), \"property\": \"color\", \"value\": \"#f00f00\"},\n        ],\n    }\n\n\n@openapi_param_value_generator([\"/users/me/subscriptions:delete\"])\ndef delete_subscription_data() -> Dict[str, object]:\n    iago = helpers.example_user(\"iago\")\n    zoe = helpers.example_user(\"ZOE\")\n    helpers.subscribe(iago, \"Verona\")\n    helpers.subscribe(iago, \"social\")\n    helpers.subscribe(zoe, \"Verona\")\n    helpers.subscribe(zoe, \"social\")\n    return {}\n\n\n@openapi_param_value_generator([\"/events:get\"])\ndef get_events() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    helpers.subscribe(profile, \"Verona\")\n    client = Client.objects.create(name=\"curl-test-client-1\")\n    response = do_events_register(profile, client, event_types=[\"message\", \"realm_emoji\"])\n    helpers.send_stream_message(helpers.example_user(\"hamlet\"), \"Verona\")\n    return {\n        \"queue_id\": response[\"queue_id\"],\n        \"last_event_id\": response[\"last_event_id\"],\n    }\n\n\n@openapi_param_value_generator([\"/events:delete\"])\ndef delete_event_queue() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    client = Client.objects.create(name=\"curl-test-client-2\")\n    response = do_events_register(profile, client, event_types=[\"message\"])\n    return {\n        \"queue_id\": response[\"queue_id\"],\n        \"last_event_id\": response[\"last_event_id\"],\n    }\n\n\n@openapi_param_value_generator([\"/users/{user_id_or_email}/presence:get\"])\ndef get_user_presence() -> Dict[str, object]:\n    iago = helpers.example_user(\"iago\")\n    client = Client.objects.create(name=\"curl-test-client-3\")\n    update_user_presence(iago, client, timezone_now(), UserPresence.ACTIVE, False)\n    return {}\n\n\n@openapi_param_value_generator([\"/users:post\"])\ndef create_user() -> Dict[str, object]:\n    return {\n        \"email\": helpers.nonreg_email(\"test\"),\n    }\n\n\n@openapi_param_value_generator([\"/user_groups/create:post\"])\ndef create_user_group_data() -> Dict[str, object]:\n    return {\n        \"members\": [helpers.example_user(\"hamlet\").id, helpers.example_user(\"othello\").id],\n    }\n\n\n@openapi_param_value_generator(\n    [\"/user_groups/{user_group_id}:patch\", \"/user_groups/{user_group_id}:delete\"]\n)\ndef get_temp_user_group_id() -> Dict[str, object]:\n    user_group, _ = UserGroup.objects.get_or_create(name=\"temp\", realm=get_realm(\"zulip\"))\n    return {\n        \"user_group_id\": user_group.id,\n    }\n\n\n@openapi_param_value_generator([\"/realm/filters/{filter_id}:delete\"])\ndef remove_realm_filters() -> Dict[str, object]:\n    filter_id = do_add_linkifier(\n        get_realm(\"zulip\"), \"#(?P<id>[0-9]{2,8})\", \"https://github.com/zulip/zulip/pull/%(id)s\"\n    )\n    return {\n        \"filter_id\": filter_id,\n    }\n\n\n@openapi_param_value_generator([\"/realm/emoji/{emoji_name}:post\", \"/user_uploads:post\"])\ndef upload_custom_emoji() -> Dict[str, object]:\n    return {\n        \"filename\": \"zerver/tests/images/animated_img.gif\",\n    }\n\n\n@openapi_param_value_generator([\"/realm/playgrounds:post\"])\ndef add_realm_playground() -> Dict[str, object]:\n    return {\n        \"name\": \"Python2 playground\",\n        \"pygments_language\": \"Python2\",\n        \"url_prefix\": \"https://python2.example.com\",\n    }\n\n\n@openapi_param_value_generator([\"/realm/playgrounds/{playground_id}:delete\"])\ndef remove_realm_playground() -> Dict[str, object]:\n    playground_info = dict(\n        name=\"Python playground\",\n        pygments_language=\"Python\",\n        url_prefix=\"https://python.example.com\",\n    )\n    playground_id = do_add_realm_playground(get_realm(\"zulip\"), **playground_info)\n    return {\n        \"playground_id\": playground_id,\n    }\n\n\n@openapi_param_value_generator([\"/users/{user_id}:delete\"])\ndef deactivate_user() -> Dict[str, object]:\n    user_profile = do_create_user(\n        email=\"testuser@zulip.com\",\n        password=None,\n        full_name=\"test_user\",\n        realm=get_realm(\"zulip\"),\n        acting_user=None,\n    )\n    return {\"user_id\": user_profile.id}\n", "path": "zerver/openapi/curl_param_value_generators.py"}], "after_files": [{"content": "# Zulip's OpenAPI-based API documentation system is documented at\n#   https://zulip.readthedocs.io/en/latest/documentation/api.html\n#\n# This file contains helper functions for generating cURL examples\n# based on Zulip's OpenAPI definitions, as well as test setup and\n# fetching of appropriate parameter values to use when running the\n# cURL examples as part of the tools/test-api test suite.\nfrom functools import wraps\nfrom typing import Any, Callable, Dict, List, Optional, Set, Tuple\n\nfrom django.utils.timezone import now as timezone_now\n\nfrom zerver.lib.actions import (\n    do_add_linkifier,\n    do_add_reaction,\n    do_add_realm_playground,\n    do_create_user,\n    update_user_presence,\n)\nfrom zerver.lib.events import do_events_register\nfrom zerver.lib.initial_password import initial_password\nfrom zerver.lib.test_classes import ZulipTestCase\nfrom zerver.lib.users import get_api_key\nfrom zerver.models import Client, Message, UserGroup, UserPresence, get_realm, get_user\n\nGENERATOR_FUNCTIONS: Dict[str, Callable[[], Dict[str, object]]] = {}\nREGISTERED_GENERATOR_FUNCTIONS: Set[str] = set()\nCALLED_GENERATOR_FUNCTIONS: Set[str] = set()\n# This is a List rather than just a string in order to make it easier\n# to write to it from another module.\nAUTHENTICATION_LINE: List[str] = [\"\"]\n\nhelpers = ZulipTestCase()\n\n\ndef openapi_param_value_generator(\n    endpoints: List[str],\n) -> Callable[[Callable[[], Dict[str, object]]], Callable[[], Dict[str, object]]]:\n    \"\"\"This decorator is used to register OpenAPI param value genarator functions\n    with endpoints. Example usage:\n\n    @openapi_param_value_generator([\"/messages/render:post\"])\n    def ...\n    \"\"\"\n\n    def wrapper(generator_func: Callable[[], Dict[str, object]]) -> Callable[[], Dict[str, object]]:\n        @wraps(generator_func)\n        def _record_calls_wrapper() -> Dict[str, object]:\n            CALLED_GENERATOR_FUNCTIONS.add(generator_func.__name__)\n            return generator_func()\n\n        REGISTERED_GENERATOR_FUNCTIONS.add(generator_func.__name__)\n        for endpoint in endpoints:\n            GENERATOR_FUNCTIONS[endpoint] = _record_calls_wrapper\n\n        return _record_calls_wrapper\n\n    return wrapper\n\n\ndef assert_all_helper_functions_called() -> None:\n    \"\"\"Throws an exception if any registered helpers were not called by tests\"\"\"\n    if REGISTERED_GENERATOR_FUNCTIONS == CALLED_GENERATOR_FUNCTIONS:\n        return\n\n    uncalled_functions = str(REGISTERED_GENERATOR_FUNCTIONS - CALLED_GENERATOR_FUNCTIONS)\n\n    raise Exception(f\"Registered curl API generators were not called: {uncalled_functions}\")\n\n\ndef patch_openapi_example_values(\n    entry: str,\n    params: List[Dict[str, Any]],\n    request_body: Optional[Dict[str, Any]] = None,\n) -> Tuple[List[Dict[str, object]], Optional[Dict[str, object]]]:\n    if entry not in GENERATOR_FUNCTIONS:\n        return params, request_body\n    func = GENERATOR_FUNCTIONS[entry]\n    realm_example_values: Dict[str, object] = func()\n\n    for param in params:\n        param_name = param[\"name\"]\n        if param_name in realm_example_values:\n            if \"content\" in param:\n                param[\"content\"][\"application/json\"][\"example\"] = realm_example_values[param_name]\n            else:\n                param[\"example\"] = realm_example_values[param_name]\n\n    if request_body is not None:\n        properties = request_body[\"content\"][\"multipart/form-data\"][\"schema\"][\"properties\"]\n        for key, property in properties.items():\n            if key in realm_example_values:\n                property[\"example\"] = realm_example_values[key]\n    return params, request_body\n\n\n@openapi_param_value_generator([\"/fetch_api_key:post\"])\ndef fetch_api_key() -> Dict[str, object]:\n    email = helpers.example_email(\"iago\")\n    password = initial_password(email)\n\n    return {\n        \"username\": email,\n        \"password\": password,\n    }\n\n\n@openapi_param_value_generator(\n    [\n        \"/messages/{message_id}:get\",\n        \"/messages/{message_id}/history:get\",\n        \"/messages/{message_id}:patch\",\n        \"/messages/{message_id}:delete\",\n    ]\n)\ndef iago_message_id() -> Dict[str, object]:\n    return {\n        \"message_id\": helpers.send_stream_message(helpers.example_user(\"iago\"), \"Denmark\"),\n    }\n\n\n@openapi_param_value_generator([\"/messages/{message_id}/reactions:delete\"])\ndef add_emoji_to_message() -> Dict[str, object]:\n    user_profile = helpers.example_user(\"iago\")\n\n    # from OpenAPI format data in zulip.yaml\n    message_id = 41\n    emoji_name = \"octopus\"\n    emoji_code = \"1f419\"\n    reaction_type = \"unicode_emoji\"\n\n    message = Message.objects.select_related().get(id=message_id)\n    do_add_reaction(user_profile, message, emoji_name, emoji_code, reaction_type)\n\n    return {}\n\n\n@openapi_param_value_generator([\"/messages/flags:post\"])\ndef update_flags_message_ids() -> Dict[str, object]:\n    stream_name = \"Venice\"\n    helpers.subscribe(helpers.example_user(\"iago\"), stream_name)\n\n    messages = []\n    for _ in range(3):\n        messages.append(helpers.send_stream_message(helpers.example_user(\"iago\"), stream_name))\n    return {\n        \"messages\": messages,\n    }\n\n\n@openapi_param_value_generator([\"/mark_stream_as_read:post\", \"/users/me/{stream_id}/topics:get\"])\ndef get_venice_stream_id() -> Dict[str, object]:\n    return {\n        \"stream_id\": helpers.get_stream_id(\"Venice\"),\n    }\n\n\n@openapi_param_value_generator([\"/streams/{stream_id}:patch\"])\ndef update_stream() -> Dict[str, object]:\n    stream = helpers.subscribe(helpers.example_user(\"iago\"), \"temp_stream 1\")\n    return {\n        \"stream_id\": stream.id,\n    }\n\n\n@openapi_param_value_generator([\"/streams/{stream_id}:delete\"])\ndef create_temp_stream_and_get_id() -> Dict[str, object]:\n    stream = helpers.subscribe(helpers.example_user(\"iago\"), \"temp_stream 2\")\n    return {\n        \"stream_id\": stream.id,\n    }\n\n\n@openapi_param_value_generator([\"/mark_topic_as_read:post\"])\ndef get_denmark_stream_id_and_topic() -> Dict[str, object]:\n    stream_name = \"Denmark\"\n    topic_name = \"Tivoli Gardens\"\n\n    helpers.subscribe(helpers.example_user(\"iago\"), stream_name)\n    helpers.send_stream_message(helpers.example_user(\"hamlet\"), stream_name, topic_name=topic_name)\n\n    return {\n        \"stream_id\": helpers.get_stream_id(stream_name),\n        \"topic_name\": topic_name,\n    }\n\n\n@openapi_param_value_generator([\"/users/me/subscriptions/properties:post\"])\ndef update_subscription_data() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    helpers.subscribe(profile, \"Verona\")\n    helpers.subscribe(profile, \"social\")\n    return {\n        \"subscription_data\": [\n            {\"stream_id\": helpers.get_stream_id(\"Verona\"), \"property\": \"pin_to_top\", \"value\": True},\n            {\"stream_id\": helpers.get_stream_id(\"social\"), \"property\": \"color\", \"value\": \"#f00f00\"},\n        ],\n    }\n\n\n@openapi_param_value_generator([\"/users/me/subscriptions:delete\"])\ndef delete_subscription_data() -> Dict[str, object]:\n    iago = helpers.example_user(\"iago\")\n    zoe = helpers.example_user(\"ZOE\")\n    helpers.subscribe(iago, \"Verona\")\n    helpers.subscribe(iago, \"social\")\n    helpers.subscribe(zoe, \"Verona\")\n    helpers.subscribe(zoe, \"social\")\n    return {}\n\n\n@openapi_param_value_generator([\"/events:get\"])\ndef get_events() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    helpers.subscribe(profile, \"Verona\")\n    client = Client.objects.create(name=\"curl-test-client-1\")\n    response = do_events_register(profile, client, event_types=[\"message\", \"realm_emoji\"])\n    helpers.send_stream_message(helpers.example_user(\"hamlet\"), \"Verona\")\n    return {\n        \"queue_id\": response[\"queue_id\"],\n        \"last_event_id\": response[\"last_event_id\"],\n    }\n\n\n@openapi_param_value_generator([\"/events:delete\"])\ndef delete_event_queue() -> Dict[str, object]:\n    profile = helpers.example_user(\"iago\")\n    client = Client.objects.create(name=\"curl-test-client-2\")\n    response = do_events_register(profile, client, event_types=[\"message\"])\n    return {\n        \"queue_id\": response[\"queue_id\"],\n        \"last_event_id\": response[\"last_event_id\"],\n    }\n\n\n@openapi_param_value_generator([\"/users/{user_id_or_email}/presence:get\"])\ndef get_user_presence() -> Dict[str, object]:\n    iago = helpers.example_user(\"iago\")\n    client = Client.objects.create(name=\"curl-test-client-3\")\n    update_user_presence(iago, client, timezone_now(), UserPresence.ACTIVE, False)\n    return {}\n\n\n@openapi_param_value_generator([\"/users:post\"])\ndef create_user() -> Dict[str, object]:\n    return {\n        \"email\": helpers.nonreg_email(\"test\"),\n    }\n\n\n@openapi_param_value_generator([\"/user_groups/create:post\"])\ndef create_user_group_data() -> Dict[str, object]:\n    return {\n        \"members\": [helpers.example_user(\"hamlet\").id, helpers.example_user(\"othello\").id],\n    }\n\n\n@openapi_param_value_generator(\n    [\"/user_groups/{user_group_id}:patch\", \"/user_groups/{user_group_id}:delete\"]\n)\ndef get_temp_user_group_id() -> Dict[str, object]:\n    user_group, _ = UserGroup.objects.get_or_create(name=\"temp\", realm=get_realm(\"zulip\"))\n    return {\n        \"user_group_id\": user_group.id,\n    }\n\n\n@openapi_param_value_generator([\"/realm/filters/{filter_id}:delete\"])\ndef remove_realm_filters() -> Dict[str, object]:\n    filter_id = do_add_linkifier(\n        get_realm(\"zulip\"), \"#(?P<id>[0-9]{2,8})\", \"https://github.com/zulip/zulip/pull/%(id)s\"\n    )\n    return {\n        \"filter_id\": filter_id,\n    }\n\n\n@openapi_param_value_generator([\"/realm/emoji/{emoji_name}:post\", \"/user_uploads:post\"])\ndef upload_custom_emoji() -> Dict[str, object]:\n    return {\n        \"filename\": \"zerver/tests/images/animated_img.gif\",\n    }\n\n\n@openapi_param_value_generator([\"/realm/playgrounds:post\"])\ndef add_realm_playground() -> Dict[str, object]:\n    return {\n        \"name\": \"Python2 playground\",\n        \"pygments_language\": \"Python2\",\n        \"url_prefix\": \"https://python2.example.com\",\n    }\n\n\n@openapi_param_value_generator([\"/realm/playgrounds/{playground_id}:delete\"])\ndef remove_realm_playground() -> Dict[str, object]:\n    playground_info = dict(\n        name=\"Python playground\",\n        pygments_language=\"Python\",\n        url_prefix=\"https://python.example.com\",\n    )\n    playground_id = do_add_realm_playground(get_realm(\"zulip\"), **playground_info)\n    return {\n        \"playground_id\": playground_id,\n    }\n\n\n@openapi_param_value_generator([\"/users/{user_id}:delete\"])\ndef deactivate_user() -> Dict[str, object]:\n    user_profile = do_create_user(\n        email=\"testuser@zulip.com\",\n        password=None,\n        full_name=\"test_user\",\n        realm=get_realm(\"zulip\"),\n        acting_user=None,\n    )\n    return {\"user_id\": user_profile.id}\n\n\n@openapi_param_value_generator([\"/users/me:delete\"])\ndef deactivate_own_user() -> Dict[str, object]:\n    test_user_email = \"delete-test@zulip.com\"\n    deactivate_test_user = do_create_user(\n        test_user_email,\n        \"secret\",\n        get_realm(\"zulip\"),\n        \"Mr. Delete\",\n        role=200,\n        acting_user=None,\n    )\n    realm = get_realm(\"zulip\")\n    test_user = get_user(test_user_email, realm)\n    test_user_api_key = get_api_key(test_user)\n    # change authentication line to allow test_client to delete itself.\n    AUTHENTICATION_LINE[0] = f\"{deactivate_test_user.email}:{test_user_api_key}\"\n    return {}\n", "path": "zerver/openapi/curl_param_value_generators.py"}]}