https://pact.io logo
#pact-python
Title
# pact-python
c

Caíque Coelho

02/20/2022, 6:49 PM
Hello everyone, I’m trying to use Verifier from pact-python in my Python Provider Api, but I’m getting failed responses in my verification. I think my problem is with Authentication, because I need to pass an Authorization Token in my request header. I’m already doing that passing the arg
custom_provider_headers
to my
verifier.verify_with_broker
but I still getting failures verifications. Someone can help me? I was wandering if there is any way to see the current response from the verification, because I only received a generic return like
has status code 200 (FAILED - 1)
there is any wait to see the actual status code return and the body response. I think if I can see the actual return will be more easy to understand what I’m doing wrong. I’m putting all my code in this thread, thank you all!
Copy code
import logging
from pact import Verifier

log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
PACT_BROKER_URL = "<https://my_pact_broker_url.pactflow.io/>"
PACT_BROKER_TOKEN = "MY_TOKEN"
PROVIDER_URL = "<https://api.release.ze.delivery/public-api>"

default_opts = {
        'broker_token': PACT_BROKER_TOKEN,
        'broker_url': PACT_BROKER_URL,
        'publish_version': '3',
        'publish_verification_results': True,
        'custom_provider_headers': ["Authorization:My_AUTH_TOKEN"],

    }

def verify_contract():
    verifier = Verifier(provider='courier-api',
                    provider_base_url=PROVIDER_URL,
                    )

    output, logs = verifier.verify_with_broker(
                    **default_opts,
                    verbose=True
    )

    print(output)
    print(logs)

verify_contract()
I’m getting the error bellow:
Copy code
Verifying a pact between courier-phoenix and courier-api [PENDING]
  A request with a new show case
    with POST /public-api
      returns a response which
        has status code 200 (FAILED - 1)
        has a matching body (FAILED - 2)
        includes headers
          "Content-Type" which equals "application/json; charset=utf-8" (FAILED - 3)

Failures:

  1) Verifying a pact between courier-phoenix and courier-api [PENDING] A request with a new show case with POST /public-api returns a response which has status code 200
     Failure/Error: replay_interaction interaction, options[:request_customizer]

     NoMethodError:
       undefined method `strip' for nil:NilClass
Should I pass
provider_states_setup_ur
with PROVIDER_URL value?
m

Matt (pactflow.io / pact-js / pact-go)

02/20/2022, 9:46 PM
Is auth token still valid?
I would consider use provider states here, though, to enable/disable the authentication component on your service when you do the tests.
Also, there should be a provider log file - pact does log it. Not sure what the Python options are, but it should create a full file log that shows the request/responses it received from your server
c

Caíque Coelho

02/22/2022, 1:54 PM
Thank you so much for your reply @Matt (pactflow.io / pact-js / pact-go), my token still valid and I was able to see the logs now, right now I’m getting this error:
Copy code
GraphQL operations must contain a non-empty `query` or a `persistedQuery` extension
I think probably I must to pass something to the Verifier class or verify_with_broker method to inform that my provider that I want to verify is a GraphQL provider. Can you help me with that, please?
m

Matt (pactflow.io / pact-js / pact-go)

02/22/2022, 9:24 PM
It shouldn’t need anything specific on the provider side. GraphQL provider presents just like any other HTTP endpoint, so that tells me the contract is probably malformed / missing something important
can you please share the conttract?
c

Caíque Coelho

03/07/2022, 2:02 PM
Hello @Matt (pactflow.io / pact-js / pact-go) thank you so much for your help, how are you? Sorry for my delay, follow my contract bellow:
Copy code
{
  "consumer": {
    "name": "courier-phoenix"
  },
  "provider": {
    "name": "courier-api"
  },
  "interactions": [
    {
      "description": "A request with a new show case",
      "request": {
        "method": "POST",
        "path": "/public-api",
        "headers": {
          "content-type": "application/json"
        },
        "body": {
          "operationName": "loadNewShowCase",
          "query": "query loadNewShowCase($filter: ShowCaseFilter) {\n  loadNewShowCase(filter: $filter) {\n    messages {\n      category\n      target\n      key\n      message\n    }\n    showCase {\n      images\n      shelves {\n        id\n        type\n        displayName\n        hasNextItems\n        items {\n          id\n          type\n          images\n          displayName\n          applicableDiscount {\n            presentedDiscountValue\n            discountType\n            finalValue\n          }\n          category {\n            id\n            displayName\n          }\n          brand {\n            id\n            displayName\n          }\n          price {\n            min\n            max\n          }\n        }\n      }\n    }\n  }\n}\n",
          "variables": {}
        },
        "matchingRules": {
          "$.body.query": {
            "match": "regex",
            "regex": "query\\s*loadNewShowCase\\(\\$filter:\\s*ShowCaseFilter\\)\\s*\\{\\s*loadNewShowCase\\(filter:\\s*\\$filter\\)\\s*\\{\\s*messages\\s*\\{\\s*category\\s*target\\s*key\\s*message\\s*\\}\\s*showCase\\s*\\{\\s*images\\s*shelves\\s*\\{\\s*id\\s*type\\s*displayName\\s*hasNextItems\\s*items\\s*\\{\\s*id\\s*type\\s*images\\s*displayName\\s*applicableDiscount\\s*\\{\\s*presentedDiscountValue\\s*discountType\\s*finalValue\\s*\\}\\s*category\\s*\\{\\s*id\\s*displayName\\s*\\}\\s*brand\\s*\\{\\s*id\\s*displayName\\s*\\}\\s*price\\s*\\{\\s*min\\s*max\\s*\\}\\s*\\}\\s*\\}\\s*\\}\\s*\\}\\s*\\}\\s*"
          }
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json; charset=utf-8"
        },
        "body": {
          "data": {
            "loadNewShowCase": {
              "messages": null,
              "showCase": {
                "images": [],
                "shelves": [
                  {
                    "id": "31239bf8-e8d8-4893-a3de-7e5316a8e6fd",
                    "type": "BILLBOARD",
                    "displayName": "Destaques",
                    "hasNextItems": false,
                    "items": [
                      {
                        "id": "b7566f41-db87-4b03-bef2-4531a5b6de50",
                        "type": "BANNER",
                        "images": [
                          "<https://courier-images-frontrelease.imgix.net/banner/b7566f41-db87-4b03-bef2-4531a5b6de50_180cab5b-ae61-4b28-9b6e-2124815cf974.jpg>"
                        ],
                        "displayName": "TESTEQA10",
                        "applicableDiscount": null,
                        "category": null,
                        "brand": null,
                        "price": null
                      }
                    ]
                  }
                ]
              }
            }
          },
          "default": {
            "data": {
              "loadNewShowCase": {
                "messages": null,
                "showCase": {
                  "images": [],
                  "shelves": [
                    {
                      "id": "31239bf8-e8d8-4893-a3de-7e5316a8e6fd",
                      "type": "BILLBOARD",
                      "displayName": "Destaques",
                      "hasNextItems": false,
                      "items": [
                        {
                          "id": "b7566f41-db87-4b03-bef2-4531a5b6de50",
                          "type": "BANNER",
                          "images": [
                            "<https://courier-images-frontrelease.imgix.net/banner/b7566f41-db87-4b03-bef2-4531a5b6de50_180cab5b-ae61-4b28-9b6e-2124815cf974.jpg>"
                          ],
                          "displayName": "TESTEQA10",
                          "applicableDiscount": null,
                          "category": null,
                          "brand": null,
                          "price": null
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "matchingRules": {
          "$.body": {
            "match": "type"
          }
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "2.0.0"
    }
  }
}
38 Views