Django + GCP (GAE, Vision API, Translate API, Cloud Storage, Cloud Firestore) で画像アプリをデプロイする。 

###目的
- Django アプリを GAE でデプロイする。
- Cloud Vision と Cloud Translate のクライアント・ライブラリー を使用する。
- Cloud Storage と Cloud Firestore にデータを保存する。

### アプリケーションの全体像

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/da2949b8-3d66-780d-ad9d-8a2222e231d8.png)



### コード
[https://github.com/takeshikondo/djangogaeimage](https://github.com/takeshikondo/djangogaeimage)

### 動作確認

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/8ca33c72-909f-2716-21e4-b307755ecffe.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/5d8804a3-894d-9013-9961-6a19ebfd53bd.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/6c924cb3-83c4-2fa4-eac3-0f7680a5a381.png)



### コードの抜粋

#### forms.py

```python
from django import forms

class ImageForm2(forms.Form):
    name = forms.CharField(
            label='Name',
            max_length=20,
            required=True,
            widget=forms.TextInput(),
            )
    image = forms.ImageField()       
```

#### views.py

```python
from django.http.response import HttpResponse
from django.shortcuts import render, redirect
from .forms import ImageForm2

def upload3(request):
    import os
    from google.cloud import storage
    from google.cloud import vision
    from google.cloud import translate
    from google.cloud import firestore
      
    # for local
    #key_path = '.app1/key/xxx.json'   
    #os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = key_path
    #CLOUD_STORAGE_BUCKET = 'bucket_name'
    
    # for deploy
    CLOUD_STORAGE_BUCKET = os.environ['CLOUD_STORAGE_BUCKET']
        
    path = 'gs://' + CLOUD_STORAGE_BUCKET + '/'
                    
    if request.method == 'POST':
        form = ImageForm2(request.POST, request.FILES)
        if form.is_valid():
            blob_name = form.cleaned_data['name']
            image = request.FILES['image']
            #image = form.cleaned_data['image']
                                    
            # Cloud Storage            
            client_storage = storage.Client()
            bucket = client_storage.get_bucket(CLOUD_STORAGE_BUCKET)            
            blob = bucket.blob(blob_name)            
            blob.upload_from_string(
                    image.read(),
                    #content_type='image/jpeg',
                    )
            
            # Vision API
            vision_client = vision.ImageAnnotatorClient()
            image = vision.types.Image()
            image.source.image_uri = path + blob_name
            response = vision_client.label_detection(image=image)
            labels = response.label_annotations
                                    
            # Cloud Firestore
            firestore_client = firestore.Client()
            doc_ref = firestore_client.collection('images').document(blob_name)
            
            d1 = labels[0].description
            s1 = labels[0].score
            d2 = labels[1].description
            s2 = labels[1].score
            d3 = labels[2].description
            s3 = labels[2].score
                                   
            doc_ref.set({
                'description1': d1,
                'scale1': s1,
                'description2': d2,
                'scale2': s2,
                'description3': d3,
                'scale3': s3,               
            })
                    
            # Translate API
            translate_client = translate.Client()
            target = 'ja'
            text1 = labels[0].description
            text2 = labels[1].description
            text3 = labels[2].description

            translation = translate_client.translate(
                    text1,
                    target_language=target)
            t1 = translation['translatedText']

            translation = translate_client.translate(
                    text2,
                    target_language=target)
            t2 = translation['translatedText']

            translation = translate_client.translate(
                    text3,
                    target_language=target)
            t3 = translation['translatedText']            
            
            d = {
                    'description1': t1,
                    'score1': '{:.3f}'.format(s1),
                    'description2': t2,
                    'score2': '{:.3f}'.format(s2),
                    'description3': t3,
                    'score3': '{:.3f}'.format(s3),
                }
             
            return render(request, 'app1/label.html', d)
        
    else:
        form = ImageForm2()   
                
    d = {
        'form': form,
    }
        
    return render(request, 'app1/upload3.html', d)
```
#### requirements.txt

```python
django
Pillow
google-api-core
google-auth
google-cloud-core
google-cloud-firestore
google-cloud-storage
google-cloud-translate
google-cloud-vision
google-resumable-media
googleapis-common-protos
grpcio
```

#### settings.py

```python
ALLOWED_HOSTS = ['*']
```

#### app.yaml
```python
runtime: python37

handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
  static_dir: static/

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
  script: auto
  
env_variables:
    CLOUD_STORAGE_BUCKET: bucket_name 
```

#### main.py

```python
from dj_project.wsgi import application

app = application
```