IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Comment utiliser PycURL pour envoyer des paramètre avec la méthode POST


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 166
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 166
    Par défaut Comment utiliser PycURL pour envoyer des paramètre avec la méthode POST
    Bonjour à tous,

    Depuis mon Raspberry, je dois envoyer des données via ma connexion WiFi, à un server distant.
    C'est un fichier PHP qui va traiter les données.

    J'ai déjà mon scropt PHP prêt, qui recois les données envoyées par The Things Network en POST.

    Laissez-moi vous expliquer en quelques lignes le but de l'exrcices pour mieux comprendre où je veux en venir.

    Sur mon Raspberry, je prends des mesures et je les envoie avec le protocole LoRaWAN à TTN (The Thinks Network). Les serveurs TTN ont un intégrateur HTTP qui va me les retourner sur mon serveur avec la méthode POST.

    Donc mon script PHP est prêt et fonctionne dans ce cas de figure.

    Actuellement, mon deuxième raspbbery ne peut pas envoyer les données avec le protocole LoRaWAN, mais il est connecté au réseau WiFi.
    Donc je dois encoyer ces même donnée directement à mon serveur, ... le même script PHP var les recevoirs et traiter les données, comme il le fait quand il les reçoit vie TTN.

    Mon fichier PHP commence comme cel

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ini_set("display_errors",1);
     
        $gmdate= gmdate("Y-m-d H:i:s");
        # Get measures from TTN
        $postdata = file_get_contents('php://input');
        # Convert json to array
        $payload = json_decode($postdata,true);

    Puis il va récupérer les données ainsi

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      $app_id = $payload['app_id'];
        $dev_id = $payload['dev_id'];
    et ainsi de suite pour les autres paramètres POST.

    Donc en ce qui concerne Python et PycURL
    J'ai trouvé un tuto qui indique comment, le faire. Mais j'ai en doute si la methode POST est bien utilisée car mon code PHP ne l'interprete pas ainsi.

    Voci ce que j'ai pour python
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    payload_curl = {}
    payload_curl["app_id"] = "aqi-sds011"
    payload_curl["dev_id"] = "sds011-12"
    payload_curl["a"] = int(pmt_2_5 * 100)      # p1 (pm2.5)
    payload_curl["b"] = int(pmt_10 * 100)       # p2 (pm10)
    payload_curl["c"] = int(aqi_2_5 * 100)      # a1 (aqi2.5)
    payload_curl["d"] = int(aqi_10 * 100)       # a2 (aqi10)
    payload_curl["e"] = int(lat * 10000)        # la (lat)
    payload_curl["f"] = int(lon * 10000)        # lo (lon)
    payload_curl["g"] = str(timestamp_now)      # ti (timestamp)
    payload_curl["h"] = int(bat1*100)           # b1 (input 1)
    payload_curl["i"] = int(bat2*100)           # b2 (input 2)
    payload_curl["j"] = int(bat3*100)           # b3 (inout 2)
    payload_curl["k"] = co2                     # co (CO2)
     
    print('[INFO] Sending data with PycURL')
    crl = pycurl.Curl()
    crl.setopt(crl.URL, 'http://www.website.ch/folder/file.php')
    # data exemple: {"app_id":"aqi-sds012","dev_id":"sds011-12","p1":"","p2":""}
    pf = urlencode(payload_curl)
    crl.setopt(crl.POSTFIELDS, pf)
    crl.perform()
    crl.close()

    Voilà ce qu'il se passe du côté PHP

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # Je recupère les données envoyées en POST
    $postdata = file_get_contents('php://input');
    # Convert json to array
    $payload = json_decode($postdata,true);
     
    # Je récupère les valeurs de app_id
    $app_id = $payload['app_id'];
    # Je récupère la valeur de dev_id
    $dev_id = $payload['dev_id'];
     
    #Pour voir ce que je recois, je le sauve les données envoyées dans un fichier de mon serveur
     
    file_put_contents('../log/tmp/'.$dev_id.'-'.gmdate("ymdHis").'.json', $postdata . PHP_EOL, FILE_APPEND);
    # Je quitte pour que le reste du code ne fasse rien de plus    
    exit();

    Je précise que ce code fonctionne très bien quand les données sont envoyées depuis TTN.

    dans la variable $postdata, je retrouve tous mes paramètres envoyés. Et je les vois aussi dans le fichier json créé dans le dossier /log/tmp/
    Donc les valeurs sont bien envoyées et reçues.

    Mais par contre, il semble que la variable $payload ne contient rien
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $payload = json_decode($postdata,true);
    car le nom du fichier json ne contien pas la valeur de dev_id

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $dev_id = $payload['dev_id'];

    Je ne comprends pas trop pourquoi, si ca marche dans un sens, pourquoi ca ne marche pas dans l'autre?

    Théoriquement l'explication que je vois
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $postdata = file_get_contents('php://input');
    $postdata n'est pas un format JSON
    donc ceci
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $payload = json_decode($postdata,true);
    Ne vas pas decoder la chaine json en array.

    Pourtant j'ai vérifié sur ma console TTN que les données sont bien envoyée en POST
    Nom : Screenshot 2020-05-21 at 23.41.27.png
Affichages : 532
Taille : 48,7 Ko

    Serait-il peut être un string au format JSON qui en envoyé en POST?
    (en écrivant ce post, peut être que je trouve la réponse )

    Mais le but de ce post est de vérifier mon script Python, si je le fais bien avec la methode POST?

    M'avez-vous suivi?

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 166
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 166
    Par défaut
    On ne peux pas dire à PycURL d'envoyer les paramètres en string json?

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 166
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 166
    Par défaut
    En fait, je crois que la solution est la suivante

    J'ai déjà ceci existant
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    jsonrow = {'dev_id': dev_id,'pm25': pmt_2_5, 'pm10': pmt_10, 'aq25': str(aqi_2_5), 'aq10': str(aqi_10), 'co2': str(co2) ,'lat': lat, 'lon': lon}

    L'idée est de fait plus simple dans ce sens (je ne mets pas toutes les variables)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    payload_curl = {}
    payload_curl['data']= "{'dev_id': sds011-12,'pm25': 120, 'pm10': 23, 'aq25': 33}"
    Ainsi data contiendra un string dans le format JSON, mais j0envoie toujours un dictionnaire payload_curl.

    Ce j'essaye de faire avec peine est comment convertir jsonrow en chaine de caractere, en conservant les {}'' et évidemment, pm25, pm10, aqi_2_5, co2, etc.... seront replacées par leurs valeurs respectives, dans jsonrow

    J'ai déjà essayé de faire ceci

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    payload_curl['data']= str(jsonrow)
    payload_curl['data'] = json.dumps(jsonrow)
    mais les deux me transforme tous les {}''

    data=%7B%27dev_id%27%3A+%27sds011-12%27%2C+%27pm25%27%3A+0.9%2C+%27pm10%27%3A+1.3%2C+%27aq25%27%3A+%274%27%2C+%27aq10%27%3A+%271%27%2C+%27co2%27%3A+%27509%27%2C+%27lat%27%3A+0%2C+%27lon%27%3A+0%2C+%27ba1%27%3A+0%2C+%27ba2%27%3A+0%2C+%27ba3%27%3A+0%2C+%27time%27%3A+1590099456.412177%7D

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 166
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 166
    Par défaut
    Est-ce possible de mettre in string dans un dictionnaire?

    jsonraw[data] = "Ma string doit contenir des { et des } ainsi que de ' ' sans que ca soit rempacé par %5C%7B%27 "

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    C'est sympa de nous faire partager les progrès de vos recherches!
    A la base vous avez beaucoup de soucis de compréhension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> d = dict(a=1, b={'c':3})
    >>> d
    {'a': 1, 'b': {'c': 3}}
    vous voyez comment s'affiche un dictionnaire Python...
    Je prend ce dictionnaire et je le transforme en JSON, j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> json.dumps(d)
    '{"a": 1, "b": {"c": 3}}'
    c'est une chaine de caractères car entre des simples quotes.
    De plus vous remarquez que les clefs sont entre double quotes.

    maintenant si j'applique urlencode:
    >>> urlencode(d)
    'a=1&b=%7B%27c%27%3A+3%7D'
    >>>

    çà c'est la partie Python de l'affaire.

    Après, urlencode, c'est pour pousser des informations dans l'URL de la requête. JSON, c'est pour en faire des données (de la même requête). Et pur utiliser le bon outil, il faut savoir à quoi ressemble la requête HTTP à faire à votre serveur PHP.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 166
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 166
    Par défaut
    Salut wiztricks

    C'est sympa de venir me filer un coupd de main.

    Le problème est claire maintenant, dans mon fichier PHP, le donnée reçues ne soit pas dans le format json
    C'est pourquoi ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $postdata = file_get_contents('php://input');
    $payload = json_decode($postdata,true);
    payload n'a pas le format voulu, soit une array, ceci parce que postdata n'est pas un json.

    Par contre dans mon cas de figure postdata est bien json (string format json)

    Donc pour résoudre mon problème depuis mon fichier python, je souhaite utilisé la variable jsonrow, ca ca existe déjà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jsonrow = {'dev_id': ttnkeys.dev_id,'p1': pmt_2_5, 'p2': pmt_10, 'a1': str(aqi_2_5), 'a2': str(aqi_10), 'co': str(co2) ,'la': lat, 'lo': lon}
    et il faut que je la stock dans un dictionnaire et je l'ai préparé ainsi

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    playload= {}
    payload['data'] = jsonrow
    et le problème (mon) est ici.

    D'abord pourquoi je veux (ou je dois) utilisé un dictionnaire, parce que comme je l'ai compris ma fonction send_curl, n'accepte qu'un dict.
    data doit etre un dictionnaire.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    def send_curl(data):
        if C_URL:
            print('[INFO] Sending data with PycURL')
            crl = pycurl.Curl()
            crl.setopt(crl.URL, 'http://demo.eco-sensors.ch/include/save_aqi.php')
            # data exemple: {"app_id":"aqi-sds012","dev_id":"sds011-12","p1":"","p2":""}
            pf = urlencode(data)
            crl.setopt(crl.POSTFIELDS, pf)
            crl.perform()
            crl.close()
            return 1
        else:
            return 0

    Donc si je reviens ici

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    playload= {}
    payload['data'] = jsonrow
    je dois faire en sorte que ca soit la meme chose que ceci (J'écourte la valeru de jsonrow)

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    playload= {}
    payload['data'] = "{'dev_id':'12','pmt_2_5':'1','pmt_10':'2'}"
    et c'est ca que je n'arrive pas faire.

    si par exemple je faire ceci

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    playload= {}
    payload['data'] = str(jsonrow)
    J'ai ceci dans mon fichier json que je sauve sur mon serveur
    data=%7B%27dev_id%27%3A+%27sds011-12%27%2C+%27p1%27%3A+0.5%2C+%27p2%27%3A+0.5%2C+%27a1%27%3A+%272%27%2C+%27a2%27%3A+%270%27%2C+%27co%27%3A+%27492%27%2C+%27la%27%3A+0%2C+%27lo%27%3A+0%2C+%27b1%27%3A+0%2C+%27b2%27%3A+0%2C+%27b3%27%3A+0%2C+%27da%27%3A+1590131760.482174%7D
    Et évidemment, ca ne va pas.

    pour rapelle
    Code pythin : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     file_put_contents('../log/tmp/'.$dev_id.'-'.gmdate("ymdHis").'.json', 
                $postdata . PHP_EOL, FILE_APPEND);

    Je constate à l'instant qu'il y a de toute maniere data= en trop. Maintenant est-ce que les %7B%27 peuvent remplacer le {' ? je ne sais pas. il faudra que je supprime le data.

    Cette nuit j'ai résolu le problème du côté PhP; mais c'est vraiment pas propre, car j'ai un if pour ce qui vient de python, et un if pour ce qui vient de TTN.

    Il faudrait vraiment que depuis python, je puisse préparer et envoyer le bon format, si c'est possible.


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Prototype] Utiliser Json pour envoyer des données au serveur
    Par GandalfZeGrey dans le forum Bibliothèques & Frameworks
    Réponses: 3
    Dernier message: 14/02/2008, 17h16
  2. Réponses: 1
    Dernier message: 15/05/2006, 18h05
  3. Réponses: 2
    Dernier message: 27/04/2006, 16h45
  4. Réponses: 4
    Dernier message: 28/03/2005, 19h42
  5. Utiliser hylafax pour envoyer des fax
    Par ggnore dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 08/07/2004, 21h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo