diff --git a/appengine/flexible_python37_and_earlier/websockets/README.md b/appengine/flexible_python37_and_earlier/websockets/README.md deleted file mode 100644 index fabd0995a40..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Python websockets sample for Google App Engine Flexible Environment - -This sample demonstrates how to use websockets on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). - -## Running locally - -Refer to the [top-level README](../README.md) for instructions on running and deploying. - -To run locally, you need to use gunicorn with the ``flask_socket`` worker: - - $ gunicorn -b 127.0.0.1:8080 -k flask_sockets.worker main:app diff --git a/appengine/flexible_python37_and_earlier/websockets/app.yaml b/appengine/flexible_python37_and_earlier/websockets/app.yaml deleted file mode 100644 index 8a323ffe30f..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/app.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -runtime: python -env: flex - -# Use a special gunicorn worker class to support websockets. -entrypoint: gunicorn -b :$PORT -k flask_sockets.worker main:app - -runtime_config: - python_version: 3 - -# Use only a single instance, so that this local-memory-only chat app will work -# consistently with multiple users. To work across multiple instances, an -# extra-instance messaging system or data store would be needed. -manual_scaling: - instances: 1 - - -# For applications which can take advantage of session affinity -# (where the load balancer will attempt to route multiple connections from -# the same user to the same App Engine instance), uncomment the folowing: - -# network: -# session_affinity: true diff --git a/appengine/flexible_python37_and_earlier/websockets/main.py b/appengine/flexible_python37_and_earlier/websockets/main.py deleted file mode 100644 index 132160d9ab5..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/main.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2018 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# [START gae_flex_websockets_app] -from flask import Flask, render_template -from flask_sockets import Sockets - - -app = Flask(__name__) -sockets = Sockets(app) - - -@sockets.route("/chat") -def chat_socket(ws): - while not ws.closed: - message = ws.receive() - if message is None: # message is "None" if the client has closed. - continue - # Send the message to all clients connected to this webserver - # process. (To support multiple processes or instances, an - # extra-instance storage or messaging system would be required.) - clients = ws.handler.server.clients.values() - for client in clients: - client.ws.send(message) - - -# [END gae_flex_websockets_app] - - -@app.route("/") -def index(): - return render_template("index.html") - - -if __name__ == "__main__": - print( - """ -This can not be run directly because the Flask development server does not -support web sockets. Instead, use gunicorn: - -gunicorn -b 127.0.0.1:8080 -k flask_sockets.worker main:app - -""" - ) diff --git a/appengine/flexible_python37_and_earlier/websockets/main_test.py b/appengine/flexible_python37_and_earlier/websockets/main_test.py deleted file mode 100644 index 597f2416d1c..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/main_test.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2018 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import socket -import subprocess - -import pytest -import requests -from retrying import retry -import websocket - - -@pytest.fixture(scope="module") -def server(): - """Provides the address of a test HTTP/websocket server. - The test server is automatically created before - a test and destroyed at the end. - """ - # Ask the OS to allocate a port. - sock = socket.socket() - sock.bind(("127.0.0.1", 0)) - port = sock.getsockname()[1] - - # Free the port and pass it to a subprocess. - sock.close() - - bind_to = f"127.0.0.1:{port}" - server = subprocess.Popen( - ["gunicorn", "-b", bind_to, "-k" "flask_sockets.worker", "main:app"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - - # With btlr, there can be many processes are spawned and the - # server might be in a tight memory situation, so let's wait for 2 - # mins. - # Wait until the server responds before proceeding. - @retry(wait_fixed=50, stop_max_delay=120000) - def check_server(url): - requests.get(url) - - check_server(f"http://{bind_to}/") - - yield bind_to - - server.kill() - - # Dump the logs for debugging - out, err = server.communicate() - print(f"gunicorn stdout: {out}") - print(f"gunicorn stderr: {err}") - - -def test_http(server): - result = requests.get(f"http://{server}/") - assert "Python Websockets Chat" in result.text - - -def test_websocket(server): - url = f"ws://{server}/chat" - ws_one = websocket.WebSocket() - ws_one.connect(url) - - ws_two = websocket.WebSocket() - ws_two.connect(url) - - message = "Hello, World" - ws_one.send(message) - - assert ws_one.recv() == message - assert ws_two.recv() == message diff --git a/appengine/flexible_python37_and_earlier/websockets/noxfile_config.py b/appengine/flexible_python37_and_earlier/websockets/noxfile_config.py deleted file mode 100644 index 1665dd736f8..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/noxfile_config.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Default TEST_CONFIG_OVERRIDE for python repos. - -# You can copy this file into your directory, then it will be imported from -# the noxfile.py. - -# The source of truth: -# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/noxfile_config.py - -TEST_CONFIG_OVERRIDE = { - # You can opt out from the test for specific Python versions. - # Skipping for Python 3.9 due to pyarrow compilation failure. - "ignored_versions": ["2.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], - # Old samples are opted out of enforcing Python type hints - # All new samples should feature them - "enforce_type_hints": False, - # An envvar key for determining the project id to use. Change it - # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a - # build specific Cloud project. You can also use your own string - # to use your own Cloud project. - "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", - # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - # A dictionary you want to inject into your test. Don't put any - # secrets here. These values will override predefined values. - "envs": {}, -} diff --git a/appengine/flexible_python37_and_earlier/websockets/requirements-test.txt b/appengine/flexible_python37_and_earlier/websockets/requirements-test.txt deleted file mode 100644 index 92b9194cf63..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/requirements-test.txt +++ /dev/null @@ -1,3 +0,0 @@ -pytest==8.2.0 -retrying==1.3.4 -websocket-client==1.7.0 diff --git a/appengine/flexible_python37_and_earlier/websockets/requirements.txt b/appengine/flexible_python37_and_earlier/websockets/requirements.txt deleted file mode 100644 index c1525d36077..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -Flask==1.1.4 # it seems like Flask-sockets doesn't play well with 2.0+ -Flask-Sockets==0.2.1 -gunicorn==23.0.0 -requests==2.31.0 -markupsafe==2.0.1 -Werkzeug==1.0.1; diff --git a/appengine/flexible_python37_and_earlier/websockets/templates/index.html b/appengine/flexible_python37_and_earlier/websockets/templates/index.html deleted file mode 100644 index af6d791f148..00000000000 --- a/appengine/flexible_python37_and_earlier/websockets/templates/index.html +++ /dev/null @@ -1,96 +0,0 @@ -{# -# Copyright 2018 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#} - - -
-Chat demo
- - -Messages:
-Status:
-