<commit_before># Nebulous Google Cloud serverless &amp; API sample application
### Run your own mini-"Google Translate" service locally, on App Engine, Cloud Functions, or Cloud Run

## Description

This is the code repo for a set of codelab tutorials highlighting a single "nebulous" sample app. What makes this app unique is that it demonstrates the flexibility of _where_ you can run your apps as far as [Google Cloud serverless](https://cloud.google.com/serverless#serverless-products) compute platforms go. With minor configuration tweaks, this app can be deployed (at least) eight different ways:

Deployment | Python 2 | Python 3
--- | --- | ---
Local/hosted Flask|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-flask?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservflask_sms_&utm_content=-)|_same as Python 2_
App Engine|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gae2?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgae2_sms_&utm_content=-)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gae3?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgae3_sms_&utm_content=-)
Cloud Functions| _N/A_ |[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcf?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcf_sms_&utm_content=-)
Cloud Run (Docker)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcr2?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcr2_sms_&utm_content=-)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcr3?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcr3_sms_&utm_content=-)
Cloud Run (Buildpacks)| _N/A_ |[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcrbp?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcrbp_sms_&utm_content=-)

Admittedly, there's a bit of "cheating" due to the duplicity of Python 2 and 3, especially since the application is compatible across both language versions without modification nor use of compatibility libraries. However there are significant differences between both App Engine runtimes beyond the version language differences. For local Flask or Cloud Run deployments, there are either little or no updates to go from 2.x to 3.x. Neither Cloud Functions nor Cloud Buildpacks support Python 2.


### Python versions

Python **== 2.7** or **>= 3.6**


### Inspiration and implementation

This code sample was inspired by a [user's suboptimal experience](https://www.mail-archive.com/google-appengine@googlegroups.com/msg94549.html) trying to create a simple App Engine app using a Cloud API. It was also inspired by a [colleague's blog post](https://dev.to/googlecloud/portable-code-migrating-across-google-cloud-s-serverless-platforms-2ifk) showing a similar Node.js example "drifting" between GCP serverless platforms.

This app shows developers how to use the [Cloud Translation API](https://cloud.google.com/translate), the API for [Google Translate](https://translate.google.com), and one of GCP's [AI/ML "building block" APIs](https://cloud.google.com/products/ai/building-blocks). Such APIs are backed by pre-trained machine learning models, allowing developers with little or no background in AI/ML to leverage machine learning with only API calls. The application implements a mini Google Translate "MVP" (minimally-viable product) web service.


### Hosting options

Aside from local deployment, this app is deployable to these serverless compute platforms:

- [Google App Engine](https://cloud.google.com/appengine) (Standard)
    - Standard source code application deployments (app-hosting in the cloud; "PaaS")
- [Google Cloud Functions](https://cloud.google.com/functions)
    - Instead of an entire app, this is for cloud-based functions or microservices ("FaaS")
- [Google Cloud Run](https://cloud.run)
    - Fully-managed serverless container-hosting in the cloud ("CaaS") service

The purpose of this app is to show users how to deploy the same app to each platform and give developers hands-on experience with each. It also shows users how similar the platforms are to each other that one can "shift" between then typically with just minor configuration changes. A fourth product, [App Engine Flexible](https://cloud.google.com/appengine/docs/flexible), which sits somewhere between App Engine Standard and Cloud Run, is out-of-scope for this sample app.

The app uses the [Flask](https://flask.palletsprojects.com) micro web framework. When deploying locally, the [Flask development server](https://flask.palletsprojects.com/en/master/server) &mdash; also see [its docs](https://flask.palletsprojects.com/server) &mdash; is used. As an application, you're likely to deploy to either App Engine or Cloud Run, depending on whether your app is containerized. Since this "app" only has a single purpose/function, it is also reasonable to deploy it to Cloud Functions.

App Engine is for users who wish to deploy a traditional web stack (LAMP, MEAN, etc.) application direct from source without knowledge of containers, Docker, nor `Dockerfile`s. Cloud Run is similar but for applications that are explicitly containerized, freeing you from language, library, or binary restrictions. Cloud Functions is for deploying simple microservices like ours, and its Python runtime sends Flask request objects directly to deployed functions.

When running on App Engine or Cloud Functions, this sample app uses the default web server that comes with those services (`gunicorn`). For Cloud Run, developers must start their own web server; this sample app again chooses Flask's development server (but can be configured to your server of choice; `gunicorn` can be enabled if uncommented in the configuration.


### Service account credentials ("local-only")

The credentials JSON file &mdash; call it anything you like, but we're using the name `credentials.json` &mdash; is only used when running locally to specify the service account used to talk to Cloud APIs. Developers are prompted to download it after [creating a service account key-pair](https://console.cloud.google.com/iam-admin/serviceaccounts/create). Check out the documentation for [service accounts](https://cloud.google.com/docs/authentication/getting-started) and the [service account public/private key/pairs](https://cloud.google.com/translate/docs/setup#service_account_and_private_key).

Why just locally? For simplicity, this sample app uses [default service accounts](https://cloud.google.com/iam/docs/service-accounts#default) when deploying to the cloud, so neither the service account key-pair created for local deployment nor its `credentials.json` will be used in those cases. In other words, if not deploying/testing locally, you don't have to create a service account key.

However, while we suggest you "delete" `credentials.json` and not use it when deploying to the cloud ("finding credentials automatically"), you can disregard that advice and opt to use that service account key-pair ("passing credentials manually") if desired as long as you point to those credentials. Read more about these options in the [documentation](https://cloud.google.com/docs/authentication/production).


### Cost

While many Google APIs can be used without fees, use of GCP products &amp; APIs is _not_ free. Certain products do offer an ["Always Free" tier](https://cloud.google.com/free/docs/gcp-free-tier#free-tier-usage-limits) which you have to exceed in order to be billed. For our purposes, while the Translation API does not explicitly list a free quota on that page, its pricing information page (link below) indicates a certain number of [translated characters](https://cloud.google.com/translate/pricing#charged-characters) as a free monthly quota applied as a credit, so long as you stay within that limit, you should not incur any additional charges. When enabling services, you may be asked for an active billing account which requires a financial instrument such as a credit card. Reference relevant pricing information before doing so.

While Cloud Functions and Cloud Run share a similar Always Free tier and pricing model, App Engine is slightly different. Here are each product's corresponding pricing pages for you to learn more as well as link to our pricing calculator:

- [App Engine](https://cloud.google.com/appengine/pricing)
- [Cloud Functions](https://cloud.google.com/functions/pricing)
- [Cloud Run](https://cloud.google.com/run/pricing)
- [Cloud Translation](https://cloud.google.com/translate/pricing)
- [GCP pricing calculator](https://cloud.google.com/products/calculator)

Furthermore, deploying to GCP serverless platforms incur [minor build and storage costs](https://cloud.google.com/appengine/pricing#pricing-for-related-google-cloud-products). [Cloud Build](https://cloud.google.com/build/pricing) has its own free quota as does [Cloud Storage](https://cloud.google.com/storage/pricing#cloud-storage-always-free). For greater transparency, Cloud Build builds your application image which is then sent to the [Cloud Container Registry](https://cloud.google.com/container-registry/pricing), or [Artifact Registry](https://cloud.google.com/artifact-registry/pricing), its successor; storage of that image uses up some of that (Cloud Storage) quota as does network egress when transferring that image to the service you're deploying to. However you may live in region that does not have such a free tier, so be aware of your storage usage to minimize potential costs. (You may look at what storage you're using and how much, including deleting build artifacts via [your Cloud Storage browser](https://console.cloud.google.com/storage/browser).)


### Enable Cloud services used

Once you have a billing account, you can enable the services/APIs for each product used. Go to the Cloud console pages for each respective Cloud product used and enable the service:

1. [App Engine](https://console.cloud.google.com/appengine)
1. [Cloud Functions](https://console.cloud.google.com/functions)
1. [Cloud Run](https://console.cloud.google.com/run)
1. [Cloud Translation](https://console.cloud.google.com/apis/api/translate.googleapis.com)

Alternatively, you use the [`gcloud` CLI (command-line interface)](https://cloud.google.com/sdk/gcloud) available from the [Cloud SDK](https://cloud.google.com/sdk). Review the [Cloud SDK install instructions](https://cloud.google.com/sdk/docs/quickstart) if needed. New users should also reference the [`gcloud` cheatsheet](https://cloud.google.com/sdk/docs/cheatsheet).

Enable all 4 services with this one `gcloud` command: `gcloud services enable translate.googleapis.com run.googleapis.com cloudfunctions.googleapis.com appengine.googleapis.com`


### The application itself

The app consists of a simple web page prompting the user for a phrase to translate from English to Spanish. The translated results along with the original phrase are presented along with an empty form for a follow-up translation if desired. While the majority of this app's deployments are in Python 3, there are still many users working on upgrading from Python 2, so some of those deployments are available to help with migration planning. This is what the app looks like after completing one translation (Cloud Run version):

![app screenshot](https://user-images.githubusercontent.com/1102504/133918482-fc66d512-aeb7-4982-bcd2-75794cd21349.png)


## Deployments and their files

These are the files provided in this repo and the deployments they're applicable to:

![repository files](https://user-images.githubusercontent.com/1102504/119735453-2f3af500-be31-11eb-9115-3fdeb22ec31c.png)

> NOTES:
>- * &mdash; `requirements.txt` is used for local and App Engine (2.x) package installations and not required in deployments themselves unlike all others
>- `main.py` and `templates/index.html` comprise the entire application and are always required
>- `noxfile.py` and `test_translate.py` are for testing only; see [Testing section](#testing) below
>- All `.*ignore` and `.git*` files/folders are administrative and not listed in table above nor deployments below
>- Files applicable only to a specific language version are annotated above

Below are the required settings and instructions for all documented deployments. The "**TL:DR;**" section at the top of each configuration summarizes the key files (see above) while the table beneath spells out the details. No administrative files are listed.


## **Local Flask server (Python 2)**<commit_msg>grammar & UTM link fixes<commit_after># Nebulous Google Cloud serverless &amp; API sample application
### Run your own mini-"Google Translate" service locally, on App Engine, Cloud Functions, or Cloud Run

## Description

This is the code repo for a set of codelab tutorials highlighting a single "nebulous" sample app. What makes this app unique is that it demonstrates the flexibility of _where_ you can run your apps as far as [Google Cloud serverless](https://cloud.google.com/serverless#serverless-products) compute platforms go. With minor configuration tweaks, this app can be deployed (at least) eight different ways:

Deployment | Python 2 | Python 3
--- | --- | ---
Local/hosted Flask|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-flask?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservflask_sms_201020&utm_content=-)|_same as Python 2_
App Engine|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gae2?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgae2_sms_201020&utm_content=-)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gae3?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgae3_sms_201020&utm_content=-)
Cloud Functions| _N/A_ |[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcf?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcf_sms_201020&utm_content=-)
Cloud Run (Docker)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcr2?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcr2_sms_201020&utm_content=-)|[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcr3?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcr3_sms_201020&utm_content=-)
Cloud Run (Buildpacks)| _N/A_ |[codelab](https://codelabs.developers.google.com/codelabs/cloud-nebulous-serverless-python-gcrbp?utm_source=codelabs&utm_medium=et&utm_campaign=CDR_wes_aap-serverless_nebservgcrbp_sms_201020&utm_content=-)

Admittedly, there may _seem_ to be a bit of "cheating" due to the duplicity of Python 2 and 3, especially since the application is compatible across both language versions without modification or use of compatibility libraries. However there are significant differences between both App Engine runtimes beyond the version language differences. For local Flask or Cloud Run deployments, there are either little or no updates to go from 2.x to 3.x. Neither Cloud Functions nor Cloud Buildpacks support Python 2.


### Python versions

Python **== 2.7** or **>= 3.6**


### Inspiration and implementation

This code sample was inspired by a [user's suboptimal experience](https://www.mail-archive.com/<EMAIL>/msg94549.html) trying to create a simple App Engine app using a Cloud API. It was also inspired by a [colleague's blog post](https://dev.to/googlecloud/portable-code-migrating-across-google-cloud-s-serverless-platforms-2ifk) showing a similar Node.js example "drifting" between GCP serverless platforms.

This app shows developers how to use the [Cloud Translation API](https://cloud.google.com/translate), the API for [Google Translate](https://translate.google.com), and one of GCP's [AI/ML "building block" APIs](https://cloud.google.com/products/ai/building-blocks). Such APIs are backed by pre-trained machine learning models, allowing developers with little or no background in AI/ML to leverage machine learning with only API calls. The application implements a mini Google Translate "MVP" (minimally-viable product) web service.


### Hosting options

Aside from local deployment, this app is deployable to these serverless compute platforms:

- [Google App Engine](https://cloud.google.com/appengine) (Standard)
    - Standard source code application deployments (app-hosting in the cloud; "PaaS")
- [Google Cloud Functions](https://cloud.google.com/functions)
    - Instead of an entire app, this is for cloud-based functions or microservices ("FaaS")
- [Google Cloud Run](https://cloud.run)
    - Fully-managed serverless container-hosting in the cloud ("CaaS") service

The purpose of this app is to show users how to deploy the same app to each platform and give developers hands-on experience with each. It also shows users how similar the platforms are to each other that one can "shift" between then typically with just minor configuration changes. A fourth product, [App Engine Flexible](https://cloud.google.com/appengine/docs/flexible), which sits somewhere between App Engine Standard and Cloud Run, is out-of-scope for this sample app.

The app uses the [Flask](https://flask.palletsprojects.com) micro web framework. When deploying locally, the [Flask development server](https://flask.palletsprojects.com/en/master/server) &mdash; also see [its docs](https://flask.palletsprojects.com/server) &mdash; is used. As an application, you're likely to deploy to either App Engine or Cloud Run, depending on whether your app is containerized. Since this "app" only has a single purpose/function, it is also reasonable to deploy it to Cloud Functions.

App Engine is for users who wish to deploy a traditional web stack (LAMP, MEAN, etc.) application direct from source without knowledge of containers, Docker, or `Dockerfile`s. Cloud Run is similar but for applications that are explicitly containerized, freeing you from language, library, or binary restrictions. Cloud Functions is for deploying simple microservices like ours, and its Python runtime sends Flask request objects directly to deployed functions.

When running on App Engine or Cloud Functions, this sample app uses the default web server that comes with those services (`gunicorn`). For Cloud Run, developers must start their own web server; this sample app again chooses Flask's development server (but can be configured to your server of choice; `gunicorn` can be enabled if uncommented in the configuration.


### Service account credentials ("local-only")

The credentials JSON file &mdash; call it anything you like, but we're using the name `credentials.json` &mdash; is only used when running locally to specify the service account used to talk to Cloud APIs. Developers are prompted to download it after [creating a service account key-pair](https://console.cloud.google.com/iam-admin/serviceaccounts/create). Check out the documentation for [service accounts](https://cloud.google.com/docs/authentication/getting-started) and the [service account public/private key/pairs](https://cloud.google.com/translate/docs/setup#service_account_and_private_key).

Why just locally? For simplicity, this sample app uses [default service accounts](https://cloud.google.com/iam/docs/service-accounts#default) when deploying to the cloud, so neither the service account key-pair created for local deployment nor its `credentials.json` will be used in those cases. In other words, if not deploying/testing locally, you don't have to create a service account key.

However, while we suggest you "delete" `credentials.json` and not use it when deploying to the cloud ("finding credentials automatically"), you can disregard that advice and opt to use that service account key-pair ("passing credentials manually") if desired as long as you point to those credentials. Read more about these options in the [documentation](https://cloud.google.com/docs/authentication/production).


### Cost

While many Google APIs can be used without fees, use of GCP products &amp; APIs is _not_ free. Certain products do offer an ["Always Free" tier](https://cloud.google.com/free/docs/gcp-free-tier#free-tier-usage-limits) which you have to exceed in order to be billed. For our purposes, while the Translation API does not explicitly list a free quota on that page, its pricing information page (link below) indicates a certain number of [translated characters](https://cloud.google.com/translate/pricing#charged-characters) as a free monthly quota applied as a credit, so long as you stay within that limit, you should not incur any additional charges. When enabling services, you may be asked for an active billing account which requires a financial instrument such as a credit card. Reference relevant pricing information before doing so.

While Cloud Functions and Cloud Run share a similar Always Free tier and pricing model, App Engine is slightly different. Here are each product's corresponding pricing pages for you to learn more as well as link to our pricing calculator:

- [App Engine](https://cloud.google.com/appengine/pricing)
- [Cloud Functions](https://cloud.google.com/functions/pricing)
- [Cloud Run](https://cloud.google.com/run/pricing)
- [Cloud Translation](https://cloud.google.com/translate/pricing)
- [GCP pricing calculator](https://cloud.google.com/products/calculator)

Furthermore, deploying to GCP serverless platforms incur [minor build and storage costs](https://cloud.google.com/appengine/pricing#pricing-for-related-google-cloud-products). [Cloud Build](https://cloud.google.com/build/pricing) has its own free quota as does [Cloud Storage](https://cloud.google.com/storage/pricing#cloud-storage-always-free). For greater transparency, Cloud Build builds your application image which is then sent to the [Cloud Container Registry](https://cloud.google.com/container-registry/pricing), or [Artifact Registry](https://cloud.google.com/artifact-registry/pricing), its successor; storage of that image uses up some of that (Cloud Storage) quota as does network egress when transferring that image to the service you're deploying to. However you may live in region that does not have such a free tier, so be aware of your storage usage to minimize potential costs. (You may look at what storage you're using and how much, including deleting build artifacts via [your Cloud Storage browser](https://console.cloud.google.com/storage/browser).)


### Enable Cloud services used

Once you have a billing account, you can enable the services/APIs for each product used. Go to the Cloud console pages for each respective Cloud product used and enable the service:

1. [App Engine](https://console.cloud.google.com/appengine)
1. [Cloud Functions](https://console.cloud.google.com/functions)
1. [Cloud Run](https://console.cloud.google.com/run)
1. [Cloud Translation](https://console.cloud.google.com/apis/api/translate.googleapis.com)

Alternatively, you use the [`gcloud` CLI (command-line interface)](https://cloud.google.com/sdk/gcloud) available from the [Cloud SDK](https://cloud.google.com/sdk). Review the [Cloud SDK install instructions](https://cloud.google.com/sdk/docs/quickstart) if needed. New users should also reference the [`gcloud` cheatsheet](https://cloud.google.com/sdk/docs/cheatsheet).

Enable all 4 services with this one `gcloud` command: `gcloud services enable translate.googleapis.com run.googleapis.com cloudfunctions.googleapis.com appengine.googleapis.com`


### The application itself

The app consists of a simple web page prompting the user for a phrase to translate from English to Spanish. The translated results along with the original phrase are presented along with an empty form for a follow-up translation if desired. While the majority of this app's deployments are in Python 3, there are still many users working on upgrading from Python 2, so some of those deployments are available to help with migration planning. This is what the app looks like after completing one translation (Cloud Run version):

![app screenshot](https://user-images.githubusercontent.com/1102504/133918482-fc66d512-aeb7-4982-bcd2-75794cd21349.png)


## Deployments and their files

These are the files provided in this repo and the deployments they're applicable to:

![repository files](https://user-images.githubusercontent.com/1102504/119735453-2f3af500-be31-11eb-9115-3fdeb22ec31c.png)

> NOTES:
>- * &mdash; `requirements.txt` is used for local and App Engine (2.x) package installations and not required in deployments themselves unlike all others
>- `main.py` and `templates/index.html` comprise the entire application and are always required
>- `noxfile.py` and `test_translate.py` are for testing only; see [Testing section](#testing) below
>- All `.*ignore` and `.git*` files/folders are administrative and not listed in table above or deployments below
>- Files applicable only to a specific language version are annotated above

Below are the required settings and instructions for all documented deployments. The "**TL:DR;**" section at the top of each configuration summarizes the key files (see above) while the table beneath spells out the details. No administrative files are listed.


## **Local Flask server (Python 2)**
{'fraction_non_alphanumeric': 0.08675870114719035, 'fraction_numerical': 0.00987750340268326, 'mean_word_length': 5.404981320049814, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 18, 'https://': 96, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7090812', 'n_tokens_mistral': 7243, 'n_tokens_neox': 6804, 'n_words': 2778}