Skip to content

Commit

Permalink
Merge pull request #112 from GoogleCloudPlatform/namespace
Browse files Browse the repository at this point in the history
Consolidate namespace example into this repo
  • Loading branch information
waprin committed Sep 24, 2015
2 parents a5a73b6 + f317bcf commit dc48bd1
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
56 changes: 56 additions & 0 deletions appengine/multitenancy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## Multitenancy Using Namespaces Sample

This is a sample app for Google App Engine that exercises the [namespace manager Python API](https://cloud.google.com/appengine/docs/python/multitenancy/multitenancy).

See our other [Google Cloud Platform github
repos](https://github.com/GoogleCloudPlatform) for sample applications and
scaffolding for other python frameworks and use cases.

## Run Locally
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.

```
gcloud components update app
gcloud auth login
gcloud config set project <your-app-id>
```
You don't need a valid app-id to run locally, but will need a valid id to deploy below.

1. Clone this repo.

```
git clone https://github.com/GoogleCloudPlatform/appengine-multitenancy-python.git
```
1. Run this project locally from the command line.

```
gcloud preview app run appengine-multitenancy-python/
```

1. Visit the application at [http://localhost:8080](http://localhost:8080).

## Deploying

1. Use the [Cloud Developer Console](https://console.developer.google.com) to create a project/app id. (App id and project id are identical)
2. Configure gcloud with your app id.

```
gcloud config set project <your-app-id>
```
1. Use the [Admin Console](https://appengine.google.com) to view data, queues, and other App Engine specific administration tasks.
1. Use gcloud to deploy your app.

```
gcloud preview app deploy appengine-multitenancy-python/
```

1. Congratulations! Your application is now live at your-app-id.appspot.com

## Contributing changes

* See [CONTRIBUTING.md](CONTRIBUTING.md)

## Licensing

* See [LICENSE](LICENSE)
22 changes: 22 additions & 0 deletions appengine/multitenancy/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file specifies your Python application's runtime configuration
# including URL routing, versions, static file uploads, etc. See
# https://developers.google.com/appengine/docs/python/config/appconfig
# for details.

version: 1
runtime: python27
api_version: 1
threadsafe: yes

# Handlers define how to route requests to your application.
handlers:

# This handler tells app engine how to route requests to a WSGI application.
# The script value is in the format <path.to.module>.<wsgi_application>
# where <wsgi_application> is a WSGI application object.
- url: .* # This regex directs all routes to main.app
script: main.app

libraries:
- name: webapp2
version: "2.5.2"
Binary file added appengine/multitenancy/favicon.ico
Binary file not shown.
63 changes: 63 additions & 0 deletions appengine/multitenancy/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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 all]
from google.appengine.api import namespace_manager
from google.appengine.ext import ndb
import webapp2


class Counter(ndb.Model):
"""Model for containing a count."""
count = ndb.IntegerProperty()


def update_counter(name):
"""Increment the named counter by 1."""

def _update_counter(inner_name):
counter = Counter.get_by_id(inner_name)
if counter is None:
counter = Counter(id=inner_name)
counter.count = 0
counter.count += 1
counter.put()

# Update counter in a transaction.
ndb.transaction(lambda: _update_counter(name))
counter = Counter.get_by_id(name)
return counter.count


class SomeRequest(webapp2.RequestHandler):
"""Perform synchronous requests to update counter."""

def get(self):
update_counter('SomeRequest')
# try/finally pattern to temporarily set the namespace.
# Save the current namespace.
namespace = namespace_manager.get_namespace()
try:
namespace_manager.set_namespace('-global-')
x = update_counter('SomeRequest')
finally:
# Restore the saved namespace.
namespace_manager.set_namespace(namespace)
self.response.write('<html><body><p>Updated counters')
self.response.write(' to %s' % x)
self.response.write('</p></body></html>')


app = webapp2.WSGIApplication([('/', SomeRequest)], debug=True)
# [END all]

0 comments on commit dc48bd1

Please sign in to comment.