diff --git a/appengine/flexible/README.md b/appengine/flexible/README.md index 66e494ffaf4..db498e5f0bb 100644 --- a/appengine/flexible/README.md +++ b/appengine/flexible/README.md @@ -7,6 +7,9 @@ These are samples for using Python on Google App Engine Flexible Environment. These samples are typically referenced from the [docs](https://cloud.google.com/appengine/docs). +For code samples of Python version 3.7 and earlier, please check +https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine/flexible. + See our other [Google Cloud Platform github repos](https://github.com/GoogleCloudPlatform) for sample applications and scaffolding for other frameworks and use cases. @@ -31,12 +34,9 @@ In general, the samples typically require: cd python-docs-samples/appengine/flexible ``` -4. Open a sample folder, create a virtualenv, install dependencies, and run the sample: +4. Follow https://cloud.google.com/python/docs/setup to set up a Python development environment. Then run: ``` - cd hello-world - virtualenv env - source env/bin/activate pip install -r requirements.txt python main.py ``` @@ -66,8 +66,8 @@ Some samples in this repositories may have special deployment instructions. Refe ## Contributing changes -* See [CONTRIBUTING.md](../CONTRIBUTING.md) +* See [CONTRIBUTING.md](../../CONTRIBUTING.md) ## Licensing -* See [LICENSE](../LICENSE) +* See [LICENSE](../../LICENSE) diff --git a/appengine/flexible/hello_world/app.yaml b/appengine/flexible/hello_world/app.yaml index 7aa7a47e159..ac38af83425 100644 --- a/appengine/flexible/hello_world/app.yaml +++ b/appengine/flexible/hello_world/app.yaml @@ -17,9 +17,9 @@ env: flex entrypoint: gunicorn -b :$PORT main:app runtime_config: - python_version: 3 + operating_system: ubuntu22 -# This sample incurs costs to run on the App Engine flexible environment. +# This sample incurs costs to run on the App Engine flexible environment. # The settings below are to reduce costs during testing and are not appropriate # for production use. For more information, see: # https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml diff --git a/appengine/flexible/hello_world/main.py b/appengine/flexible/hello_world/main.py index 8a5a5a9f6fc..ebbd393ef54 100644 --- a/appengine/flexible/hello_world/main.py +++ b/appengine/flexible/hello_world/main.py @@ -1,4 +1,4 @@ -# Copyright 2015 Google LLC. +# Copyright 2015 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ @app.route('/') -def hello(): +def hello() -> str: """Return a friendly HTTP greeting.""" return 'Hello World!' diff --git a/appengine/flexible/hello_world/main_test.py b/appengine/flexible/hello_world/main_test.py index 8bdbf76a920..341059c348d 100644 --- a/appengine/flexible/hello_world/main_test.py +++ b/appengine/flexible/hello_world/main_test.py @@ -1,4 +1,4 @@ -# Copyright 2015 Google LLC. +# Copyright 2015 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ import main -def test_index(): +def test_index() -> str: main.app.testing = True client = main.app.test_client() diff --git a/appengine/flexible_ubuntu/hello_world/noxfile_config.py b/appengine/flexible/hello_world/noxfile_config.py similarity index 100% rename from appengine/flexible_ubuntu/hello_world/noxfile_config.py rename to appengine/flexible/hello_world/noxfile_config.py diff --git a/appengine/flexible/hello_world/requirements-test.txt b/appengine/flexible/hello_world/requirements-test.txt index c2845bffbe8..95ea1e6a02b 100644 --- a/appengine/flexible/hello_world/requirements-test.txt +++ b/appengine/flexible/hello_world/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==6.2.4 diff --git a/appengine/flexible/hello_world/requirements.txt b/appengine/flexible/hello_world/requirements.txt index beeed7bed09..b690bf61e0a 100644 --- a/appengine/flexible/hello_world/requirements.txt +++ b/appengine/flexible/hello_world/requirements.txt @@ -1,3 +1,2 @@ -Flask==2.1.0; python_version > '3.6' -Flask==2.0.3; python_version < '3.7' +Flask==2.1.1 gunicorn==20.1.0 diff --git a/appengine/flexible/pubsub/README.md b/appengine/flexible/pubsub/README.md index c4c65500681..47707840594 100644 --- a/appengine/flexible/pubsub/README.md +++ b/appengine/flexible/pubsub/README.md @@ -32,10 +32,9 @@ When running locally, you can use the [Google Cloud SDK](https://cloud.google.co $ gcloud init -Install dependencies, preferably with a virtualenv: +Install dependencies, please follow https://cloud.google.com/python/docs/setup +to set up a Python development environment. Then run: - $ virtualenv env - $ source env/bin/activate $ pip install -r requirements.txt Then set environment variables before starting your application: diff --git a/appengine/flexible/pubsub/app.yaml b/appengine/flexible/pubsub/app.yaml index 5804ac2b266..95175b76687 100644 --- a/appengine/flexible/pubsub/app.yaml +++ b/appengine/flexible/pubsub/app.yaml @@ -17,7 +17,7 @@ env: flex entrypoint: gunicorn -b :$PORT main:app runtime_config: - python_version: 3 + operating_system: "ubuntu22" # [START gae_flex_pubsub_env] env_variables: diff --git a/appengine/flexible/static_files/app.yaml b/appengine/flexible/static_files/app.yaml index ca76f83fc3b..3605c19a7cb 100644 --- a/appengine/flexible/static_files/app.yaml +++ b/appengine/flexible/static_files/app.yaml @@ -17,4 +17,4 @@ env: flex entrypoint: gunicorn -b :$PORT main:app runtime_config: - python_version: 3 + operating_system: "ubuntu22" diff --git a/appengine/flexible/storage/app.yaml b/appengine/flexible/storage/app.yaml index e21a4c0ae91..fdfb9e7e3d1 100644 --- a/appengine/flexible/storage/app.yaml +++ b/appengine/flexible/storage/app.yaml @@ -17,9 +17,9 @@ env: flex entrypoint: gunicorn -b :$PORT main:app runtime_config: - python_version: 3 + operating_system: "ubuntu22" #[START gae_flex_storage_yaml] env_variables: - CLOUD_STORAGE_BUCKET: your-bucket-name + CLOUD_STORAGE_BUCKET: [your-bucket-name] #[END gae_flex_storage_yaml] diff --git a/appengine/flexible/storage/main.py b/appengine/flexible/storage/main.py index 6a20d7c05c5..98a363a6c3c 100644 --- a/appengine/flexible/storage/main.py +++ b/appengine/flexible/storage/main.py @@ -1,4 +1,4 @@ -# Copyright 2015 Google LLC. +# Copyright 2015 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,10 +23,10 @@ app = Flask(__name__) # Configure this environment variable via app.yaml -CLOUD_STORAGE_BUCKET = os.environ['CLOUD_STORAGE_BUCKET'] +CLOUD_STORAGE_BUCKET = os.environ["CLOUD_STORAGE_BUCKET"] -@app.route('/') +@app.route("/") def index() -> str: return """
@@ -36,13 +36,13 @@ def index() -> str: """ -@app.route('/upload', methods=['POST']) +@app.route("/upload", methods=["POST"]) def upload() -> str: """Process the uploaded file and upload it to Google Cloud Storage.""" - uploaded_file = request.files.get('file') + uploaded_file = request.files.get("file") if not uploaded_file: - return 'No file uploaded.', 400 + return "No file uploaded.", 400 # Create a Cloud Storage client. gcs = storage.Client() @@ -54,8 +54,7 @@ def upload() -> str: blob = bucket.blob(uploaded_file.filename) blob.upload_from_string( - uploaded_file.read(), - content_type=uploaded_file.content_type + uploaded_file.read(), content_type=uploaded_file.content_type ) # Make the blob public. This is not necessary if the @@ -69,15 +68,20 @@ def upload() -> str: @app.errorhandler(500) def server_error(e: Union[Exception, int]) -> str: - logging.exception('An error occurred during a request.') - return """ + logging.exception("An error occurred during a request.") + return ( + """ An internal error occurred:
{}
See logs for full stacktrace. - """.format(e), 500 + """.format( + e + ), + 500, + ) -if __name__ == '__main__': +if __name__ == "__main__": # This is used when running locally. Gunicorn is used to run the # application on Google App Engine. See entrypoint in app.yaml. - app.run(host='127.0.0.1', port=8080, debug=True) + app.run(host="127.0.0.1", port=8080, debug=True) # [END gae_flex_storage_app] diff --git a/appengine/flexible/storage/main_test.py b/appengine/flexible/storage/main_test.py index 9b6ef6d3f9e..b0ce34bd1f0 100644 --- a/appengine/flexible/storage/main_test.py +++ b/appengine/flexible/storage/main_test.py @@ -1,4 +1,4 @@ -# Copyright 2015 Google LLC. +# Copyright 2015 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import io import os import uuid @@ -19,8 +20,8 @@ import flask.testing from google.cloud import storage import pytest + import requests -from six import BytesIO import main @@ -32,7 +33,7 @@ def client() -> flask.testing.FlaskClient: def test_index(client: flask.testing.FlaskClient) -> None: - r = client.get('/') + r = client.get("/") assert r.status_code == 200 @@ -50,17 +51,12 @@ def test_upload(client: flask.testing.FlaskClient, blob_name: str) -> None: # Upload a simple file file_content = b"This is some test content." - r = client.post( - '/upload', - data={ - 'file': (BytesIO(file_content), blob_name) - } - ) + r = client.post("/upload", data={"file": (io.BytesIO(file_content), blob_name)}) assert r.status_code == 200 # The app should return the public cloud storage URL for the uploaded # file. Download and verify it. - cloud_storage_url = r.data.decode('utf-8') + cloud_storage_url = r.data.decode("utf-8") r = requests.get(cloud_storage_url) - assert r.text.encode('utf-8') == file_content + assert r.text.encode("utf-8") == file_content diff --git a/appengine/flexible/storage/noxfile_config.py b/appengine/flexible/storage/noxfile_config.py index 1016bb530e8..094d4b44480 100644 --- a/appengine/flexible/storage/noxfile_config.py +++ b/appengine/flexible/storage/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/appengine/flexible/storage/requirements-test.txt b/appengine/flexible/storage/requirements-test.txt index 6b6d2af7b81..e6323c66f62 100644 --- a/appengine/flexible/storage/requirements-test.txt +++ b/appengine/flexible/storage/requirements-test.txt @@ -1,3 +1,2 @@ pytest==7.0.1 -google-cloud-storage==2.0.0; python_version < '3.7' -google-cloud-storage==2.1.0; python_version > '3.6' +google-cloud-storage==2.1.0; diff --git a/appengine/flexible/storage/requirements.txt b/appengine/flexible/storage/requirements.txt index 2e8e0ffb03f..e254bb503e7 100644 --- a/appengine/flexible/storage/requirements.txt +++ b/appengine/flexible/storage/requirements.txt @@ -1,8 +1,4 @@ -Flask==2.1.0; python_version > '3.6' -Flask==2.0.3; python_version < '3.7' -werkzeug==2.1.2; python_version > '3.6' -werkzeug==2.0.3; python_version < '3.7' -google-cloud-storage==2.0.0; python_version < '3.7' -google-cloud-storage==2.1.0; python_version > '3.6' -gunicorn==20.1.0; python_version > '3.0' -gunicorn==19.10.0; python_version < '3.0' +Flask==2.1.0; +werkzeug==2.1.2; +google-cloud-storage==2.1.0; +gunicorn==20.1.0; diff --git a/appengine/flexible/tasks/app.yaml b/appengine/flexible/tasks/app.yaml index 15ac0d97205..7260c1706a9 100644 --- a/appengine/flexible/tasks/app.yaml +++ b/appengine/flexible/tasks/app.yaml @@ -1,10 +1,10 @@ -# Copyright 2019 Google LLC. +# Copyright 2019 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 +# 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, @@ -12,4 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -runtime: python37 +runtime: python +env: flex +entrypoint: gunicorn -b :$PORT main:app + +runtime_config: + operating_system: "ubuntu22" diff --git a/appengine/flexible/tasks/templates/index.html b/appengine/flexible/tasks/templates/index.html index 7e4efc7b336..c1050e716cf 100644 --- a/appengine/flexible/tasks/templates/index.html +++ b/appengine/flexible/tasks/templates/index.html @@ -18,4 +18,4 @@

Printed task payload: {{ payload }}

- \ No newline at end of file + diff --git a/appengine/flexible_ubuntu/README.md b/appengine/flexible_ubuntu/README.md deleted file mode 100644 index 5b2fb5a2f59..00000000000 --- a/appengine/flexible_ubuntu/README.md +++ /dev/null @@ -1,76 +0,0 @@ -## Google App Engine Flexible Environment Python on Ubuntu Samples - -[![Open in Cloud Shell][shell_img]][shell_link] - -[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png -[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=appengine/flexible_ubuntu/README.md - -These are samples for using Python on Google App Engine Flexible Environment on the Ubuntu 18 and Ubuntu 22 OS. These samples are typically referenced from the [docs](https://cloud.google.com/appengine/docs). - -See our other [Google Cloud Platform github repos](https://github.com/GoogleCloudPlatform) for sample applications and -scaffolding for other frameworks and use cases. - -## Run Locally - -Some samples have specific instructions. If there is a README in the sample folder, please refer to it for any additional steps required to run the sample. - -In general, the samples typically require: - -1. Install the [Google Cloud SDK](https://cloud.google.com/sdk/), including the [gcloud tool](https://cloud.google.com/sdk/gcloud/), and [gcloud app component](https://cloud.google.com/sdk/gcloud-app). - -2. Setup the gcloud tool. This provides authentication to Google Cloud APIs and services. - - ``` - gcloud init - ``` - -3. Clone this repo. - - ``` - git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git - cd python-docs-samples/appengine/flexible - ``` - -4. Open a sample folder, create a virtualenv, install dependencies, and run the sample: - - ``` - cd hello-world - virtualenv env - source env/bin/activate - pip install -r requirements.txt - python main.py - ``` - -5. Visit the application at [http://localhost:8080](http://localhost:8080). - - -## Deploying - -Some samples in this repositories may have special deployment instructions. Refer to the readme in the sample directory. - -1. Use the [Google Developers Console](https://console.developer.google.com) to create a project/app id. (App id and project id are identical) - -2. Setup the gcloud tool, if you haven't already. - - ``` - gcloud init - ``` - -3. Use gcloud to deploy your app. Your application must use a `gcloud` CLI - [version **420.0.0 or later**](/sdk/docs/install-sdk#installing_the_latest_version). - To view the current `gcloud` version, run the [`gcloud - version`](/sdk/gcloud/reference/version) command. - - ``` - gcloud app deploy - ``` - -4. Congratulations! Your application is now live at `your-app-id.appspot.com` - -## Contributing changes - -* See [CONTRIBUTING.md](../CONTRIBUTING.md) - -## Licensing - -* See [LICENSE](../LICENSE) diff --git a/appengine/flexible_ubuntu/hello_world/app.yaml b/appengine/flexible_ubuntu/hello_world/app.yaml deleted file mode 100644 index 617e5495b28..00000000000 --- a/appengine/flexible_ubuntu/hello_world/app.yaml +++ /dev/null @@ -1,34 +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 -entrypoint: gunicorn -b :$PORT main:app - -runtime_config: - operating_system: ubuntu22 - # We also support 3.8, 3.9 and 3.11. - # See https://cloud.google.com/appengine/docs/flexible/python/runtime#interpreter for more info. - runtime_version: "3.10" - -# This sample incurs costs to run on the App Engine flexible environment. -# The settings below are to reduce costs during testing and are not appropriate -# for production use. For more information, see: -# https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml -manual_scaling: - instances: 1 -resources: - cpu: 1 - memory_gb: 0.5 - disk_size_gb: 10 diff --git a/appengine/flexible_ubuntu/hello_world/main.py b/appengine/flexible_ubuntu/hello_world/main.py deleted file mode 100644 index d238f1a6f46..00000000000 --- a/appengine/flexible_ubuntu/hello_world/main.py +++ /dev/null @@ -1,32 +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. - -# [START gae_flex_quickstart] -from flask import Flask - - -app = Flask(__name__) - - -@app.route('/') -def hello() -> str: - """Return a friendly HTTP greeting.""" - return 'Hello World!' - - -if __name__ == '__main__': - # This is used when running locally only. When deploying to Google App - # Engine, a webserver process such as Gunicorn will serve the app. - app.run(host='127.0.0.1', port=8080, debug=True) -# [END gae_flex_quickstart] diff --git a/appengine/flexible_ubuntu/hello_world/main_test.py b/appengine/flexible_ubuntu/hello_world/main_test.py deleted file mode 100644 index 2a025c095e6..00000000000 --- a/appengine/flexible_ubuntu/hello_world/main_test.py +++ /dev/null @@ -1,24 +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. - -import main - - -def test_index() -> str: - main.app.testing = True - client = main.app.test_client() - - r = client.get('/') - assert r.status_code == 200 - assert 'Hello World' in r.data.decode('utf-8') diff --git a/appengine/flexible_ubuntu/hello_world/requirements-test.txt b/appengine/flexible_ubuntu/hello_world/requirements-test.txt deleted file mode 100644 index 95ea1e6a02b..00000000000 --- a/appengine/flexible_ubuntu/hello_world/requirements-test.txt +++ /dev/null @@ -1 +0,0 @@ -pytest==6.2.4 diff --git a/appengine/flexible_ubuntu/hello_world/requirements.txt b/appengine/flexible_ubuntu/hello_world/requirements.txt deleted file mode 100644 index b690bf61e0a..00000000000 --- a/appengine/flexible_ubuntu/hello_world/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Flask==2.1.1 -gunicorn==20.1.0 diff --git a/appengine/flexible_ubuntu/storage/README.md b/appengine/flexible_ubuntu/storage/README.md deleted file mode 100644 index 9d15e0d3785..00000000000 --- a/appengine/flexible_ubuntu/storage/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Python Google Cloud Storage sample for Google App Engine Flexible Environment - -[![Open in Cloud Shell][shell_img]][shell_link] - -[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png -[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=appengine/flexible_ubuntu/storage/README.md - -This sample demonstrates how to use [Google Cloud Storage](https://cloud.google.com/storage/) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). - -## Setup - -Before you can run or deploy the sample, you will need to do the following: - -1. Enable the Cloud Storage API in the [Google Developers Console](https://console.developers.google.com/project/_/apiui/apiview/storage/overview). - -2. Create a Cloud Storage Bucket. You can do this with the [Google Cloud SDK](https://cloud.google.com/sdk) with the following command: - - $ gsutil mb gs://[your-bucket-name] - -3. Set the default ACL on your bucket to public read in order to serve files directly from Cloud Storage. You can do this with the [Google Cloud SDK](https://cloud.google.com/sdk) with the following command: - - $ gsutil defacl set public-read gs://[your-bucket-name] - -4. Update the environment variables in ``app.yaml``. - -## Running locally - -Refer to the [top-level README](../README.md) for instructions on running and deploying. - -When running locally, you can use the [Google Cloud SDK](https://cloud.google.com/sdk) to provide authentication to use Google Cloud APIs: - - $ gcloud init - -Then set environment variables before starting your application: - - $ export CLOUD_STORAGE_BUCKET=[your-bucket-name] - $ python main.py diff --git a/appengine/flexible_ubuntu/storage/app.yaml b/appengine/flexible_ubuntu/storage/app.yaml deleted file mode 100644 index 59577b9ee8c..00000000000 --- a/appengine/flexible_ubuntu/storage/app.yaml +++ /dev/null @@ -1,28 +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. - -runtime: python -env: flex -entrypoint: gunicorn -b :$PORT main:app - -runtime_config: - # We also support 3.8, 3.9 and 3.10. - # See https://cloud.google.com/appengine/docs/flexible/python/runtime#interpreter for more info. - runtime_version: "3.11" - operating_system: "ubuntu22" - -#[START gae_flex_storage_yaml] -env_variables: - CLOUD_STORAGE_BUCKET: [your-bucket-name] -#[END gae_flex_storage_yaml] diff --git a/appengine/flexible_ubuntu/storage/main.py b/appengine/flexible_ubuntu/storage/main.py deleted file mode 100644 index 0664d2aa9ab..00000000000 --- a/appengine/flexible_ubuntu/storage/main.py +++ /dev/null @@ -1,87 +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. - -# [START gae_flex_ubuntu_storage_app] -import logging -import os -from typing import Union - -from flask import Flask, request -from google.cloud import storage - -app = Flask(__name__) - -# Configure this environment variable via app.yaml -CLOUD_STORAGE_BUCKET = os.environ["CLOUD_STORAGE_BUCKET"] - - -@app.route("/") -def index() -> str: - return """ - - - -
-""" - - -@app.route("/upload", methods=["POST"]) -def upload() -> str: - """Process the uploaded file and upload it to Google Cloud Storage.""" - uploaded_file = request.files.get("file") - - if not uploaded_file: - return "No file uploaded.", 400 - - # Create a Cloud Storage client. - gcs = storage.Client() - - # Get the bucket that the file will be uploaded to. - bucket = gcs.get_bucket(CLOUD_STORAGE_BUCKET) - - # Create a new blob and upload the file's content. - blob = bucket.blob(uploaded_file.filename) - - blob.upload_from_string( - uploaded_file.read(), content_type=uploaded_file.content_type - ) - - # Make the blob public. This is not necessary if the - # entire bucket is public. - # See https://cloud.google.com/storage/docs/access-control/making-data-public. - blob.make_public() - - # The public URL can be used to directly access the uploaded file via HTTP. - return blob.public_url - - -@app.errorhandler(500) -def server_error(e: Union[Exception, int]) -> str: - logging.exception("An error occurred during a request.") - return ( - """ - An internal error occurred:
{}
- See logs for full stacktrace. - """.format( - e - ), - 500, - ) - - -if __name__ == "__main__": - # This is used when running locally. Gunicorn is used to run the - # application on Google App Engine. See entrypoint in app.yaml. - app.run(host="127.0.0.1", port=8080, debug=True) -# [END gae_flex_ubuntu_storage_app] diff --git a/appengine/flexible_ubuntu/storage/main_test.py b/appengine/flexible_ubuntu/storage/main_test.py deleted file mode 100644 index 36d02f83354..00000000000 --- a/appengine/flexible_ubuntu/storage/main_test.py +++ /dev/null @@ -1,62 +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. - -import io -import os -import uuid - -import flask -import flask.testing -from google.cloud import storage -import pytest - -import requests - -import main - - -@pytest.fixture -def client() -> flask.testing.FlaskClient: - main.app.testing = True - return main.app.test_client() - - -def test_index(client: flask.testing.FlaskClient) -> None: - r = client.get("/") - assert r.status_code == 200 - - -@pytest.fixture(scope="module") -def blob_name() -> str: - name = f"gae-flex-storage-{uuid.uuid4()}" - yield name - - bucket = storage.Client().bucket(os.environ["CLOUD_STORAGE_BUCKET"]) - blob = bucket.blob(name) - blob.delete() - - -def test_upload(client: flask.testing.FlaskClient, blob_name: str) -> None: - # Upload a simple file - file_content = b"This is some test content." - - r = client.post("/upload", data={"file": (io.BytesIO(file_content), blob_name)}) - - assert r.status_code == 200 - - # The app should return the public cloud storage URL for the uploaded - # file. Download and verify it. - cloud_storage_url = r.data.decode("utf-8") - r = requests.get(cloud_storage_url) - assert r.text.encode("utf-8") == file_content diff --git a/appengine/flexible_ubuntu/storage/noxfile_config.py b/appengine/flexible_ubuntu/storage/noxfile_config.py deleted file mode 100644 index 44097a85005..00000000000 --- a/appengine/flexible_ubuntu/storage/noxfile_config.py +++ /dev/null @@ -1,44 +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. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"], - # Old samples are opted out of enforcing Python type hints - # All new samples should feature them - "enforce_type_hints": True, - # 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', - # If you need to use a specific version of pip, - # change pip_version_override to the string representation - # of the version number, for example, "20.2.4" - "pip_version_override": None, - # A dictionary you want to inject into your test. Don't put any - # secrets here. These values will override predefined values. - "envs": { - "CLOUD_STORAGE_BUCKET": "python-docs-samples-tests-public" - }, -} diff --git a/appengine/flexible_ubuntu/storage/requirements-test.txt b/appengine/flexible_ubuntu/storage/requirements-test.txt deleted file mode 100644 index e6323c66f62..00000000000 --- a/appengine/flexible_ubuntu/storage/requirements-test.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest==7.0.1 -google-cloud-storage==2.1.0; diff --git a/appengine/flexible_ubuntu/storage/requirements.txt b/appengine/flexible_ubuntu/storage/requirements.txt deleted file mode 100644 index e254bb503e7..00000000000 --- a/appengine/flexible_ubuntu/storage/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -Flask==2.1.0; -werkzeug==2.1.2; -google-cloud-storage==2.1.0; -gunicorn==20.1.0;