Python Graphene

Python Graphene

Python被认为是最受欢迎的通用编程语言之一,因为它易于使用和简单。除此之外,GraphQL是一种声明性的查询语言,用于应用程序编程接口和服务器运行时,与Python非常搭配。然而,目前提供给程序员的关于如何在Python中使用GraphQL的逐步教程非常少。

Graphene是在像Python这样的编程语言中创建GraphQL端点的最佳库之一。它具有动态进化的特点。它包含了适用于Django、SQLAlchemy和MongoDB的相当完整的ORM帮助库。实现一些简单的功能非常容易。Graphene的文档还有很大的提升空间。通过它的文档,使用GraphQL实现一些简单的功能是非常容易的;然而,要实现一些复杂、生产就绪和强大的功能则是另一回事。

在接下来的教程中,我们将重点介绍如何使用Graphene库在Python中使用GraphQL。

但在进入正题之前,让我们简要讨论一下教程的目标和要求。

目标

我们将构建一个基于爬取服务的项目。我们将使用抓取库来完成这个项目。

这个爬取服务将以以下方式提交客户端请求:

{
    website(url: "https://www.javatpoint.com/python-tutorial") {
        title
        image
    }
}

服务器的响应将会是:

{
    "data": {
        "website": {
            "title": "Learn Python Tutorial - javatpoint",
            "image": "https://static.javatpoint.com/images/logo/jtp_logo",
        }
    }
}

每个网站还将涉及一个描述字段。

设置环境

假设我们已经有本地可用的Python 3版本,让我们首先为依赖项创建一个虚拟环境。为了创建一个虚拟环境,让我们先安装virtualenv,如下所示:

语法:

$ pip install virtualenv
$ virtualenv env

输出:

created virtual environment CPython3.9.0.final.0-64 in 45108ms
  creator CPython3Windows(dest=D:\Python\env, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\Mango\AppData\Local\pypa\virtualenv)
    added seed packages: pip==21.2.2, setuptools==57.4.0, wheel==0.36.2
  activators BashActivator,BatchActivator,FishActivator,PowerShellActivator,PythonActivator

让我们激活虚拟环境。

Windows、macOS和Linux的语法非常不同。

1.对于Windows:

语法:

$ env\Scripts\activate

2.对于 MacOS / Linux:

语法:

$ source env/bin/activate

现在,我们来了解一下项目所需的库。

  1. Extraction
  2. Graphene
  3. Flask-graphql
  4. Requests

我们可以使用pip安装它们,如下所示。

语法:

$ pip install extraction
$ pip install graphene
$ pip install flask-graphql
$ pip install requests

或者

我们可以按照下面所示的方式将它们作为一组安装:

语法:

$ pip install extraction graphene flask-graphql requests

抓取和提取数据

在我们开始学习GraphQL之前,让我们简要了解一下从网站中抓取和提取数据的代码片段。

示例:

# importing the required libraries
import graphene
import extraction
import requests
# defining the function for extraction
def extract(myurl):
    myhtml = requests.get(myurl).text
    extrctd = extraction.Extractor().extract(myhtml, source_url = myurl)
    print(extrctd)
# calling the function
extract('https://www.javatpoint.com/python-tutorial')

输出:

解释:

在上面的代码片段中,我们导入了所需的库并定义了一个名为 extract() 的提取函数。

在函数内部,我们使用requests模块请求URL的详细信息,并将这些详情存储在名为 myhtml 的变量中。然后,我们使用提取模块的 Extractor()

函数来提取用户所需的数据,并将其打印给用户。

最后,我们调用 extract() 函数,指定我们要从中提取数据的URL。

我们可以观察到,每个提取的对象生成可用的不同数据部分,如 title、url、image、descriptionfeed。

结构

GraphQL结构位于每个GraphQL API的基础上。它有助于描述暴露的API的类型、字段和对象。我们使用Graphene库将模式描述为Python中的对象。

我们可以以非常简单的方式编写描述提取的网站的模式,如下所示:

示例:

# importing the graphene library
import graphene
# defining a class
class my_Website(graphene.ObjectType):
    my_url = graphene.String(required = True)
    my_title = graphene.String()
    my_description = graphene.String()
    my_image = graphene.String()

解释:

在上面的代码片段中,我们导入了graphene库并定义了一个类, myWebsite 该类继承了graphene库的 ObjectType 类。这个 ObjectType 作为一个构建块,用于定义模式中字段与检索其数据的方式之间的关系。在类内部,我们定义了不同的字段,并使用graphene库的 String() 描述字段的类型; 多个字段可能是我们描述的其他对象或者其他 链表,标量,枚举, 等等。

非常意外的是,我们还需要编写一个描述查询的模式,以便检索这些对象:

示例:

# importing the graphene library
import graphene
# defining the class
class my_Query(graphene.ObjectType):
    website1 = graphene.Field(my_Website, my_url = graphene.String())
    # defining the function
    def resolv_website(self, info, my_url):
        extrctd = extract(my_url)
        return my_Website(my_url = my_url,
                       my_title = extrctd.title,
                       my_description = extrctd.description,
                       my_image = extrctd.image,
        )

解释:

在上面的代码片段中, website1 是我们支持查询的对象类型, my_url 是我们将传递给解析函数的参数,然后 website1 对象通过每个请求调用 resolv_website 函数。

最后一步是创建 graphene.Schema 的一个实例,我们将在服务器中传递该实例,以描述我们创建的新API。让我们考虑以下相同的代码片段。

示例:

my_schema = graphene.Schema(query = my_Query)

完成这些操作后,我们成功地为项目创建了模式。

以下是完整的代码:

文件:my_schema.py

# importing the required libraries
import graphene
import extraction
import requests
# defining the function for extraction
def extract(my_url):
    myhtml = requests.get(my_url).text
    extrctd = extraction.Extractor().extract(myhtml, source_url = my_url)
    print(extrctd)
    return extrctd
# defining the class
class my_Website(graphene.ObjectType):
    my_url = graphene.String(required = True)
    my_title = graphene.String()
    my_description = graphene.String()
    my_image = graphene.String()
# defining the class
class my_Query(graphene.ObjectType):
    website1 = graphene.Field(my_Website, my_url = graphene.String())
    # defining the function
    def resolv_website(self, info, my_url):
        extrctd = extract(my_url)
        return my_Website(my_url = my_url,
                       my_title = extrctd.title,
                       my_description = extrctd.description,
                       my_image = extrctd.image,
        )

my_schema = graphene.Schema(query = my_Query)

服务器

现在我们已经编写了模式,我们可以使用 flaskflask-graphql 的帮助来通过HTTP提供服务。

让我们考虑以下代码片段来创建一个服务器。

**文件:my_server.py**

# importing the required library
from flask import Flask
from flask_graphql import GraphQLView
import my_schema
# using the Flask() function to create app
my_app = Flask(__name__)
# setting URL rules
my_app.add_url_rule(
  '/',
  view_func = GraphQLView.as_view('graphql', schema = my_schema, graphiql = True)
)
my_app.run()

说明:

在上面的代码片段中,我们导入了所需的库,并导入了之前创建的名为 my_schema 的文件。然后,我们使用 Flask() 函数,并指定参数为 __name__ 来创建应用程序。我们还使用 add_url_rule() 函数来添加不同的URL规则,其中我们指定了不同的参数,并在最后使用 run() 函数来执行应用程序。

现在,我们可以使用以下语法运行服务器:

语法:

$ python my_server.py

一旦我们输入了上述语法,服务器将开始运行在 localhost:5000 或者 http://127.0.0.1:5000/.

相同操作的输出如下所示:

输出:

Serving Flask app "my_server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

客户端

尽管存在这些,但我们不需要特殊的GraphQL客户端来执行对新API的API请求; 我们可以继续使用我们习惯于的HTTP客户端,我们在以下示例中使用请求。

文件: my_client.py

# importing the requests library
import requests
# defining the query
my_query = """
{
  website(url: "https://www.javatpoint.com/python-tutorial") {
    title
    image
    description
  }
}
"""
# defining the response
my_response = requests.post("http://127.0.0.1:5000/", params = {'query': my_query})
print(my_response.text)

输出:

{
  "data": {
    "website": {
      "title": "Learn Python Tutorial - javatpoint",
      "image": "https://static.javatpoint.com/images/logo/jtp_logo",
      "description": "Learn Python Tutorial for beginners and profession"
    }
  }
}

解释:

在上面的代码片段中,我们导入了 requests 库,并定义了一个查询 my_query ,该查询将发送到服务器。然后,我们定义了一个变量 my_response, 它将以响应的形式存储从服务器返回的数据。最后,我们打印出响应给用户。

用户还可以自定义 my_query 变量的内容,以检索不同的字段,甚至可以使用别名一次检索多个对象。

自省

在GraphQL中最强大的方面之一是它的服务器支持自省。自省允许人类和自动化工具理解可用的对象和操作。

一个很好的示例是,当我们运行我们构建的示例时,我们可以导航到 http://127.0.0.1:5000 并直接使用GraphiQL测试新的API。

这些能力不仅限于GraphiQL,我们还可以借助相同的查询接口进行集成,以查询新的API。让我们考虑一个简单的示例,我们询问示例服务暴露的可用查询:

{
  __type(name: "Query") {
    fields {
      name
      args {
        name
      }
    }
  }
}

服务器回答会是:

{
  "data": {
    "__type": {
      "fields": [
        {
          "name": "website",
          "args": [{ "name": "url" }]
        }
      ]
    }
  }
}

有很多基于内省的其他查询可用,编写起来非常笨拙;然而,它们为工具构建者提供了巨大的力量。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程