FactualCat-Twitter-Bot icon indicating copy to clipboard operation
FactualCat-Twitter-Bot copied to clipboard

GCP throws `TypeError: hello_pubsub() missing 1 required positional argument: 'context'`

Open ChristianOConnor opened this issue 3 years ago • 1 comments

When I run gcp_function.py in GCP as a cloud function, it throws TypeError: hello_pubsub() missing 1 required positional argument: 'context'

Expected behavior

I expect my account it to tweet a cat fact.

Actual behavior

No Tweet occurs in my Twitter account and I have the following log in my GCP Cloud Function

Traceback (most recent call last):
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/functions_framework/__init__.py", line 99, in view_func
    return function(request._get_current_object())
TypeError: hello_pubsub() missing 1 required positional argument: 'context'

When I remove context from the input of hello_pubsub, I get this error

Traceback (most recent call last):
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/functions_framework/__init__.py", line 99, in view_func
    return function(request._get_current_object())
  File "/workspace/main.py", line 27, in crow1_pubsub
    request = requests.post(
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/api.py", line 112, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/sessions.py", line 494, in request
    prep = self.prepare_request(req)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/sessions.py", line 427, in prepare_request
    p.prepare(
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/models.py", line 309, in prepare
    self.prepare_auth(auth, url)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests/models.py", line 540, in prepare_auth
    r = auth(self)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/requests_oauthlib/oauth1_auth.py", line 108, in __call__
    r.url, headers, _ = self.client.sign(
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/__init__.py", line 351, in sign
    ('oauth_signature', self.get_oauth_signature(request)))
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/__init__.py", line 165, in get_oauth_signature
    uri, headers, body = self._render(request)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/__init__.py", line 247, in _render
    headers = parameters.prepare_headers(
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/utils.py", line 25, in wrapper
    return target(params, *args, **kwargs)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/parameters.py", line 53, in prepare_headers
    escaped_value = utils.escape(value)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/oauthlib/oauth1/rfc5849/utils.py", line 49, in escape
    raise ValueError('Only unicode objects are escapable. ' +
ValueError: Only unicode objects are escapable. Got None of type <class 'NoneType'>.

Steps to reproduce the behavior

All I did was copy the contents of the file gcp_function.py and put it into a GCP cloud function. Also I created the secrets with my secret manager and imported them via environment variables called CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET. It's also worth noting that I'm running this function through a service account.

The local version of this app cat_fact_bot.py ran from my terminal works perfectly.

I tried to just print out CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET via this cloud function:

import os

consumer_key = os.environ.get("CONSUMER_KEY")
consumer_secret = os.environ.get("CONSUMER_SECRET")
access_token = os.environ.get("ACCESS_TOKEN")
access_token_secret = os.environ.get("ACCESS_TOKEN_SECRET")

def hello_world(request):
    """Responds to any HTTP request.
    Args:
        request (flask.Request): HTTP request object.
    Returns:
        The response text or any set of values that can be turned into a
        Response object using
        `make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`.
    """
    request_json = request.get_json()
    if request.args and 'message' in request.args:
        return request.args.get('message')
    elif request_json and 'message' in request_json:
        return request_json['message']
    else:
        return consumer_key + ' ' + consumer_secret + ' ' + acccess_token + ' ' + access_token_secret

And I got this error:

Traceback (most recent call last):
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/layers/google.python.pip/pip/lib/python3.9/site-packages/functions_framework/__init__.py", line 99, in view_func
    return function(request._get_current_object())
  File "/workspace/main.py", line 23, in hello_world
    return consumer_key + ' ' + consumer_secret + ' ' + acccess_token + ' ' + access_token_secret
NameError: name 'acccess_token' is not defined

I think this is because ACCESS_TOKEN has a hyphen (-) in it. How do I make sure it reads this value properly as a string even with a hyphen?

ChristianOConnor avatar May 20 '22 08:05 ChristianOConnor

How are you invoking your function? You also need to wrap your function with either functions_framework.http or functions_framework.cloud_event (I'm guessing http)

So it looks like this:

@functions_framework.http
def hello_world(request):
    """Responds to any HTTP request.
    Args:

The ValueError just looks like you haven't correctly authorized your environment but I could be wrong.

kirby-jack avatar Apr 16 '25 07:04 kirby-jack