如何从python向AppSync发送GraphQL查询?

问题描述 投票:1回答:1

我们如何使用boto通过AWS AppSync发布GraphQL请求?

最终,我正在尝试模仿一个移动应用程序,但该应用程序使用python访问AWS上的无堆栈/云信息堆栈。不是javascript或放大。

主要的痛点是身份验证;我已经尝试了十二种不同的方法。这是当前的消息,它生成一个带有“ UnauthorizedException”和“权限被拒绝”的“ 401”响应,考虑到我收到的其他一些消息,这实际上是相当不错的。我现在正在使用“ aws_requests_auth”库来执行签名部分。我假设它使用本地环境中存储的/.aws/credentials对我进行身份验证,还是对?

我对认知身份和集合将进入何处以及如何进入感到困惑。例如:说我想模仿注册顺序?

无论如何,代码看起来非常简单;我只是不验证身份。

from aws_requests_auth.boto_utils import BotoAWSRequestsAuth

APPSYNC_API_KEY = 'inAppsyncSettings'
APPSYNC_API_ENDPOINT_URL = 'https://aaaaaaaaaaaavzbke.appsync-api.ap-southeast-2.amazonaws.com/graphql'

headers = {
    'Content-Type': "application/graphql",
    'x-api-key': APPSYNC_API_KEY,
    'cache-control': "no-cache",
}
query = """{
    GetUserSettingsByEmail(email: "john@washere"){
      items {name, identity_id, invite_code}
    }
}"""


def test_stuff():
    # Use the library to generate auth headers.
    auth = BotoAWSRequestsAuth(
        aws_host='aaaaaaaaaaaavzbke.appsync-api.ap-southeast-2.amazonaws.com',
        aws_region='ap-southeast-2',
        aws_service='appsync')

    # Create an http graphql request.
    response = requests.post(
        APPSYNC_API_ENDPOINT_URL, 
        json={'query': query}, 
        auth=auth, 
        headers=headers)

    print(response)

# this didn't work:
#    response = requests.post(APPSYNC_API_ENDPOINT_URL, data=json.dumps({'query': query}), auth=auth, headers=headers)

收益率

{
  "errors" : [ {
    "errorType" : "UnauthorizedException",
    "message" : "Permission denied"
  } ]
}
python-3.x boto3 aws-appsync
1个回答
1
投票

非常简单-一旦知道。有些事情我不喜欢:

  1. 我承担过IAM身份验证appsync有多种方法来处理身份验证。我们正在使用IAM,所以这就是我需要处理的,您的可能会有所不同。

  2. Boto没有加入。我们希望像任何常规下注者一样发出请求,他们不使用boto,我们也不这样做。拖曳AWS Boto文档是浪费时间。

  3. 使用AWS4Auth库我们将向aws发送regular http请求,因此尽管我们可以使用python requests python,但它们需要通过附加标头进行身份验证。而且,当然,AWS auth标头是特殊的,并且与所有其他标头不同。You can try to work out how to do it yourself,或者您可以寻找已经做过的其他人:Aws_requests_auth,我刚开始使用的那个,可能效果很好,但我最终得到了AWS4Auth。还有许多其他价值可疑的东西。没有得到亚马逊认可或提供的(我可以找到)。

  4. appsync指定为“服务”我们在叫什么服务?我在任何地方都没有找到任何这样做的例子。所有示例都是琐碎的S3或EC2甚至是EB,这些都留下了不确定性。我们应该和api网关服务通话吗?此外,您将此详细信息输入到AWS4Auth例程中或身份验证数据。显然,事后看来,该请求已到达Appsync,因此它将由Appsync进行身份验证,因此在将auth标头放在一起时,将“ appsync”指定为service

它合在一起为:

import requests
from requests_aws4auth import AWS4Auth

# Use AWS4Auth to sign a requests session
session = requests.Session()
session.auth = AWS4Auth(
    # An AWS 'ACCESS KEY' associated with an IAM user.
    'AKxxxxxxxxxxxxxxx2A',
    # The 'secret' that goes with the above access key.                    
    'kwWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgEm',    
    # The region you want to access.
    'ap-southeast-2',
    # The service you want to access.
    'appsync'
)
# As found in AWS Appsync under Settings for your endpoint.
APPSYNC_API_ENDPOINT_URL = 'https://nqxxxxxxxxxxxxxxxxxxxke'
                           '.appsync-api.ap-southeast-2.amazonaws.com/graphql'
# Use JSON format string for the query. It does not need reformatting.
query = """
    query foo {
        GetUserSettings (
           identity_id: "ap-southeast-2:8xxxxxxb-7xx4-4xx4-8xx0-exxxxxxx2"
        ){ 
           user_name, email, whatever 
}}"""
# Now we can simply post the request...
response = session.request(
    url=APPSYNC_API_ENDPOINT_URL,
    method='POST',
    json={'query': query}
)
print(response.text)

哪个产量

# Your answer comes as a JSON formatted string in the text attribute, under data. 
{"data":{"GetUserSettings":{"user_name":"0xxxxxxx3-9102-42f0-9874-1xxxxx7dxxx5"}}}

获取凭据

要摆脱硬编码的密钥/秘密,您可以使用本地AWS ~/.aws/config~/.aws/credentials,并且可以通过这种方式完成...

    credentials = boto3.session.Session().get_credentials()
...
    credentials.access_key,
    credentials.secret_key,
    credentials.token
    boto3.session.Session().region_name

这似乎确实尊重环境变量AWS_PROFILE承担不同的角色。

请注意,STS.get_session_token不是这样做的方法,因为它可能会尝试从某个角色中扮演一个角色,具体取决于它与AWS_PROFILE值匹配的关键字。 credentials文件中的标签将起作用,因为键就在那里,但是config文件中的名称不起作用,因为这已经假定了角色。

© www.soinside.com 2019 - 2024. All rights reserved.