[PYTHON] Créer et renvoyer un fichier CSV CP932 pour Excel avec Chalice

introduction

Lors de la création d'un système de gestion d'applications Web, je rencontre souvent le modèle «Je veux que vous puissiez télécharger les données système dans un fichier CSV qui peut être ouvert dans Excel». Si vous créez un CSV sans penser à quoi que ce soit dans Python3, ce sera un codage de caractères UTF-8, donc s'il s'agit du paramètre par défaut d'Excel, les caractères seront déformés. Bien sûr, si vous spécifiez correctement l'encodage de lecture dans Excel, vous pouvez l'ouvrir sans problème, mais on dit souvent que "je ne comprends pas ça, alors ne déformez pas depuis le début". Dans ce cas, il est nécessaire de créer un fichier CSV avec l'encodage pour Windows (CP932, ou Shift_JIS, SJIS).

Cette fois, j'utilisais Chalice, mais après avoir regardé attentivement le document, je suis resté coincé, alors j'ai pris une note.

version etc.

$ pipenv run chalice --version
chalice 1.21.2, python 3.8.2, linux 5.4.0-52-generic

Lire la documentation

Cette fois, je veux le renvoyer avec Response, j'ai donc pensé que ce serait possible si je mettais une valeur appropriée dans le corps de la classe Response. Cependant, le document au moment de la rédaction de l'article (23 octobre 2020) indique:

class Response(body, headers=None, status_code=200) body: The HTTP response body to send back. This value must be a string.

Cité et extrait de https://aws.github.io/chalice/api.html#response. Partiellement souligné.

Penser en lisant ceci.

"Eh ...? La chaîne de caractères encodée en CP932 est de type octets, donc je ne peux pas la passer ici ...? Si ce n'est pas possible, créez un fichier, téléchargez-le sur S3 et faites-le télécharger ..."

Cependant, même si vous mettez des octets dans ** body, il passera **. Il semble que la «chaîne» dans ce document soit destinée à une chaîne plus large que le «type str». Quand j'ai cherché à nouveau, Une personne avec la même question m'a posé une question.

Exemple de mise en œuvre: réponse directe

Vous pouvez également passer le ** type d'octets ** au Response # body ** de Chalice. Si vous l'implémentez en fonction de cela, cela ressemblera à ceci. Si vous accédez à / avec un navigateur, il sera téléchargé sous forme de fichier CSV.

app.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

import csv
import tempfile

from chalice import Chalice, Response

app = Chalice(app_name='csvtest')


def csv_response(filename, encoding='utf8'):
    """Comment renvoyer un fichier CSV 1:Réponse directe"""
    with tempfile.TemporaryFile(mode='r+', encoding=encoding) as fh:
        #Ecrire avec l'écrivain
        writer = csv.writer(fh, lineterminator='\r\n')
        writer.writerow(['Nom d'utilisateur', 'Date et heure de connexion'])
        writer.writerow(['user01', '2000/01/01 00:00:00'])
        #Lire toutes les données écrites en données
        fh.seek(0)
        data = fh.read()
    headers = {}
    headers['Content-Type'] = 'text/csv'
    headers['Content-Disposition'] = f'attachment;filename="{filename}"'
    return Response(body=data, status_code=200, headers=headers)


@app.route('/')
def index():
    return csv_response('test.csv', encoding='cp932')

Alternative: télécharger des fichiers sur S3

Dans l'exemple précédent, «tmpfile» est utilisé pour créer un fichier en mémoire, puis «data» est lu. Cependant, dans le cas d'AWS Lambda, il est exécuté dans un environnement où l'utilisation de la mémoire est limitée, on peut donc imaginer que l'utilisation de la mémoire sera considérablement affectée lorsque le fichier devient volumineux. Bien sûr, c'est un problème qui peut être évité en augmentant la limite supérieure d'utilisation de la mémoire, mais si la charge double, vous pouvez hésiter. Dans ce cas, vous pouvez créer temporairement un fichier sous / tmp fourni par AWS Lambda et télécharger le fichier créé sur S3. Après le téléchargement sur S3, vous pouvez accéder au fichier créé via la communication de CloudFront --S3, ou créer et fournir une URL temporaire pour permettre à l'utilisateur de le télécharger.

Notez que «TempfileContext» n'est pas l'essence du code car il est préparé pour que les fichiers sous «/ tmp» utilisés dans AWS Lambda puissent être supprimés sans tenir compte de la gestion des erreurs.

import os
import csv
import uuid

import boto3

s3 = boto3.client('s3')


class TempfileContext:
    """Fournit un contexte pour créer et supprimer des fichiers temporaires"""
    def __init__(self):
        tmpfile = str(uuid.uuid4())
        self.filename = f'/tmp/{tmpfile}'

    def __enter__(self):
        return self

    def __exit__(self, ex_type, ex_value, trace):
        try:
            if os.path.exists(self.filename):
                os.remove(self.filename)
        except Exception:
            pass


def create_and_upload_csv(filename, encoding='utf8'):
    """Comment renvoyer un fichier CSV 2:Créez un CSV et téléchargez-le sur S3"""
    with TempfileContext() as tmp:
        # 1. /Créez un fichier CSV dans la zone tmp
        with open(tmp.filename, 'w', encoding=encoding) as fh:
            #Ecrire avec l'écrivain
            writer = csv.writer(fh, lineterminator='\n')
            writer.writerow(['Nom d'utilisateur', 'Date et heure de connexion'])
            writer.writerow(['user01', '2000/01/01 00:00:00'])

        # 2.Télécharger vers S3
        s3.upload_file(tmp.filename, BUCKETNAME, f'uploads/{filename}')

Recommended Posts

Créer et renvoyer un fichier CSV CP932 pour Excel avec Chalice
Créez un fichier temporaire avec django sous forme de zip et renvoyez-le
Créer un téléchargeur de fichiers avec Django
Créez une illusion rayée avec correction gamma pour Python3 et openCV3
Créez rapidement un fichier Excel avec Python #python
Créer un gros fichier texte avec shellscript
Créer une machine virtuelle avec un fichier YAML (KVM)
Créer un fichier Excel avec Python + matrice de similarité
Lire et formater des fichiers csv mélangés avec des tabulations de virgule avec des pandas Python
Comment lire un fichier CSV avec Python 2/3
Créer un fichier exécutable GUI créé avec tkinter
Créer un LINE BOT avec Minette pour Python
Créer un fichier PDF avec une taille de page aléatoire
Créez un tableau de bord pour les appareils réseau avec Django!
Créer un cylindre avec une sortie de fichier open3d + STL
Créons un système de réception simple avec le framework sans serveur Python Chalice et Twilio
Créez une base de données propre pour les tests avec FastAPI et effectuez le test Unittest de l'API avec pytest
Créez une application graphique native avec Py2app et Tkinter
Créez un lot d'images et gonflez avec ImageDataGenerator
Créer une couche pour AWS Lambda Python dans Docker
Créer une visionneuse de modèle 3D avec PyQt5 et PyQtGraph
Script Python qui crée un fichier JSON à partir d'un fichier CSV
[Python] Créez un fichier de distribution pour le programme Tkinter avec cx_Freeze
Créer un fichier CAO 2D ".dxf" avec python [ezdxf]
[Linux] Créez un auto-certificat avec Docker et apache
Créez un fichier audio avec la fonction de synthèse vocale de Google Text To Speak et vérifiez le texte comme guide de parole pendant 3 minutes.
Analysez l'API Researchmap avec Python et créez automatiquement un fichier Word pour la liste des succès
Créer un nouveau csv avec des pandas basé sur le csv local
[Python] Créez un écran de spécification de chemin de fichier et de dossier avec tkinter
Créez une caméra de surveillance WEB avec Raspberry Pi et OpenCV
[Python] Lisez le fichier csv et affichez la figure avec matplotlib
[Python] Créer une liste de dates et d'heures pour une période spécifiée
Créez des applications, enregistrez des données et partagez-les avec un seul e-mail
Créons un diagramme PRML avec Python, Numpy et matplotlib.
Procédure d'installation pour Python et Ansible avec une version spécifique
Technique élégante pour coller des données CSV dans Excel avec Python
Créez un script de déploiement avec fabric et cuisine et réutilisez-le
Bibliothèque pour spécifier un serveur de noms en python et dig
Créez une API d'intégration sociale pour les applications smartphone avec Django
[Python] Créer un écran pour le code d'état HTTP 403/404/500 avec Django
Avec moi, cp et sous-processus
Lire et écrire un fichier csv
Créer une page d'accueil avec django
Lire et écrire des fichiers
Créer un fichier de données factice
Écrire et lire des fichiers
Créer un répertoire avec python
Créer un fichier xlsx avec XlsxWriter
Créer un environnement d'exécution Windows Python avec VScode + Remote WSL
Comment coller un fichier CSV dans un fichier Excel à l'aide de Pandas
Créons une IA à trois voies avec Pylearn2 --Save and load model -
Créez un sélecteur de couleurs pour la roue chromatique avec Python + Qt (PySide)
Comment créer une étiquette (masque) pour la segmentation avec labelme (masque de segmentation sémantique)
Créez un DMP privé sans coût initial ni développement avec BigQuery
J'ai essayé de créer des taureaux et des vaches avec un programme shell
[Pour les débutants] Lisez des fichiers Excel / CSV dans DataFrame avec Google Colaboratory