标签归档:api

WhatsApp API(java / python)[关闭]

问题:WhatsApp API(java / python)[关闭]

我正在寻找WhatsApp API,最好是Python或Java库。

我已经尝试过Yowsup,但是无法注册我的电话号码;我住在印度,不知道是否与印度有任何关系。

我确实尝试过WhatsAPI(Python库),但也不起作用。

有什么建议吗?这里有Yowsup的用户吗?

I am looking for WhatsApp API, preferably a Python or Java library.

I’ve tried Yowsup, but could not get my number registered; I am based in India and I am not sure if that has got anything to do with it.

I did try WhatsAPI (Python library) but it is not working either.

Any suggestions about this? Any users of Yowsup here?


回答 0

尝试了一切之后,Yowsup库为我工作。我所面对的错误已得到修复。任何尝试使用Whatsapp做某事的人都应该尝试一下。

After trying everything, Yowsup library worked for me. The bug that I was facing was recently fixed. Anyone trying to do something with Whatsapp should try it.


回答 1

从我的博客

礼貌

WhatsApp正在与特定企业合作开展一项秘密试点计划

新闻报道:

对于我的一些技术实验,我试图从市场份额以及适应的可能性方面,弄清为不同的聊天平台实现机器人的好处和可行性。尤其是当您破产两次失败时,重要的是验证想法并更快地失败。

流行的聊天平台,例如MessengerSlack Skype等,已经很高兴(正式意义上)提供了与机器人进行交互的API,但是WhatsApp尚未提供任何API。

然而,多年来,围绕此发生了许多活动-努力与WhatsApp平台进行自动交互:

  1. Bots App Bots App很有趣,因为它表明某些东西确实经过尝试和测试。

  2. Yowsup 一个仍在积极开发以与WhatsApp平台进行交互的项目。

  3. Yallagenie Yallagenie声称有一个演示机器人可以与+971 56 112 6652进行交互

  4. Hubtype Hubtype正在努力为商务WhatsApp建立一个机器人平台。

  5. 弗雷德· 弗雷德(Fred Fred)的任务是使WhatsApp对话自动化,但是由于WhatsApp并未正式支持该对话,因此已将其关闭。

  6. Oye Gennie, 一个 WhatsApp 阻止的机器人。

  7. 应用程序/网站到WhatsApp 我们可以使用自定义URL方案和Android意向系统与WhatsApp进行交互,但仍不能与WhatsApp API进行交互。

  8. 聊天API守护程序 可能是通过检查WhatsApp Web版本中的API调用而创建的。不隶属于WhatsApp。

  9. WhatsBot 停用了WhatsApp机器人。在hackathon期间创建的。

  10. 没有API声明 WhatsApp联合创始人在一次会议上明确表示他们没有针对WhatsApp API的任何计划。

  11. Bot Ware 他们可能期望WhatsApp为聊天机器人平台发布其API。

  12. Vixi 他们似乎在谈论某种平台可能适用于WhatsApp。尚无明确说明。

  13. 非官方API 该API可以随时关闭。

    而且这个数字还在继续…

From my blog

courtesy

There is a secret pilot program which WhatsApp is working on with selected businesses

News coverage:

For some of my technical experiments, I was trying to figure out how beneficial and feasible it is to implement bots for different chat platforms in terms of market share and so possibilities of adaptation. Especially when you have bankruptly failed twice, it’s important to validate ideas and fail more faster.

Popular chat platforms like Messenger, Slack, Skype etc. have happily (in the sense officially) provided APIs for bots to interact with, but WhatsApp has not yet provided any API.

However, since many years, a lot of activities has happened around this – struggle towards automated interaction with WhatsApp platform:

  1. Bots App Bots App is interesting because it shows that something is really tried and tested.

  2. Yowsup A project still actively developed to interact with WhatsApp platform.

  3. Yallagenie Yallagenie claim that there is a demo bot which can be interacted with at +971 56 112 6652

  4. Hubtype Hubtype is working towards having a bot platform for WhatsApp for business.

  5. Fred Fred’s task was to automate WhatsApp conversations, however since it was not officially supported by WhatsApp – it was shut down.

  6. Oye Gennie A bot blocked by WhatsApp.

  7. App/Website to WhatsApp We can use custom URL schemes and Android intent system to interact with WhatsApp but still NOT WhatsApp API.

  8. Chat API daemon Probably created by inspecting the API calls in WhatsApp web version. NOT affiliated with WhatsApp.

  9. WhatsBot Deactivated WhatsApp bot. Created during a hackathon.

  10. No API claim WhatsApp co-founder clearly stated this in a conference that they did not had any plans for APIs for WhatsApp.

  11. Bot Ware They probably are expecting WhatsApp to release their APIs for chat bot platforms.

  12. Vixi They seems to be talking about how some platform which probably would work for WhatsApp. There is no clarity as such.

  13. Unofficial API This API can shut off any time.

    And the number goes on…


回答 2

Yowsup提供了最佳的解决方案示例。您可以从https://github.com/tgalal/yowsup下载api,如果有任何问题,告诉我。

Yowsup provide best solution with example.you can download api from https://github.com/tgalal/yowsup let me know if you have any issue.


回答 3

WhatsApp Inc.不提供开放的API,但由GitHub上的Venomous团队在GitHub上提供了反向工程库。但是据我所知,这在PHP中成为可能。您可以在此处查看链接:https : //github.com/venomous0x/WhatsAPI

希望这可以帮助

WhatsApp Inc. does not provide an open API but a reverse-engineered library is made available on GitHub by the team Venomous on the GitHub. This however according to my knowledge is made possible in PHP. You can check the link here: https://github.com/venomous0x/WhatsAPI

Hope this helps


回答 4

这是Open WhatsApp官方页面的开发人员页面:http : //openwhatsapp.org/develop/

您可以在那里找到有关Yowsup的很多信息。

或者,您可以直接访问库的链接(无论如何我都是从Open WhatsApp页面复制的):https : //github.com/tgalal/yowsup

请享用!

This is the developers page of the Open WhatsApp official page: http://openwhatsapp.org/develop/

You can find a lot of information there about Yowsup.

Or, you can just go the the library’s link (which I copied from the Open WhatsApp page anyway): https://github.com/tgalal/yowsup

Enjoy!


Httpbin-HTTP请求和响应服务,用Python+Flask编写

使用Python sqlite3 API的表,数据库模式,转储等的列表

问题:使用Python sqlite3 API的表,数据库模式,转储等的列表

由于某种原因,我找不到一种方法来获取与sqlite的交互式shell命令等效的方法:

.tables
.dump

使用Python sqlite3 API。

有没有类似的东西?

For some reason I can’t find a way to get the equivalents of sqlite’s interactive shell commands:

.tables
.dump

using the Python sqlite3 API.

Is there anything like that?


回答 0

您可以通过查询SQLITE_MASTER表来获取表和模式列表:

sqlite> .tab
job         snmptarget  t1          t2          t3        
sqlite> select name from sqlite_master where type = 'table';
job
t1
t2
snmptarget
t3

sqlite> .schema job
CREATE TABLE job (
    id INTEGER PRIMARY KEY,
    data VARCHAR
);
sqlite> select sql from sqlite_master where type = 'table' and name = 'job';
CREATE TABLE job (
    id INTEGER PRIMARY KEY,
    data VARCHAR
)

You can fetch the list of tables and schemata by querying the SQLITE_MASTER table:

sqlite> .tab
job         snmptarget  t1          t2          t3        
sqlite> select name from sqlite_master where type = 'table';
job
t1
t2
snmptarget
t3

sqlite> .schema job
CREATE TABLE job (
    id INTEGER PRIMARY KEY,
    data VARCHAR
);
sqlite> select sql from sqlite_master where type = 'table' and name = 'job';
CREATE TABLE job (
    id INTEGER PRIMARY KEY,
    data VARCHAR
)

回答 1

在Python中:

con = sqlite3.connect('database.db')
cursor = con.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
print(cursor.fetchall())

当心我的其他答案。使用熊猫有更快的方法。

In Python:

con = sqlite3.connect('database.db')
cursor = con.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
print(cursor.fetchall())

Watch out for my other answer. There is a much faster way using pandas.


回答 2

在python中执行此操作的最快方法是使用Pandas(版本0.16及更高版本)。

转储一张桌子:

db = sqlite3.connect('database.db')
table = pd.read_sql_query("SELECT * from table_name", db)
table.to_csv(table_name + '.csv', index_label='index')

转储所有表:

import sqlite3
import pandas as pd


def to_csv():
    db = sqlite3.connect('database.db')
    cursor = db.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    for table_name in tables:
        table_name = table_name[0]
        table = pd.read_sql_query("SELECT * from %s" % table_name, db)
        table.to_csv(table_name + '.csv', index_label='index')
    cursor.close()
    db.close()

The FASTEST way of doing this in python is using Pandas (version 0.16 and up).

Dump one table:

db = sqlite3.connect('database.db')
table = pd.read_sql_query("SELECT * from table_name", db)
table.to_csv(table_name + '.csv', index_label='index')

Dump all tables:

import sqlite3
import pandas as pd


def to_csv():
    db = sqlite3.connect('database.db')
    cursor = db.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    for table_name in tables:
        table_name = table_name[0]
        table = pd.read_sql_query("SELECT * from %s" % table_name, db)
        table.to_csv(table_name + '.csv', index_label='index')
    cursor.close()
    db.close()

回答 3

我不熟悉Python API,但您可以随时使用

SELECT * FROM sqlite_master;

I’m not familiar with the Python API but you can always use

SELECT * FROM sqlite_master;

回答 4

这是一个简短的python程序,用于打印出这些表的表名和列名(后接python2。python 3)。

import sqlite3

db_filename = 'database.sqlite'
newline_indent = '\n   '

db=sqlite3.connect(db_filename)
db.text_factory = str
cur = db.cursor()

result = cur.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall()
table_names = sorted(zip(*result)[0])
print "\ntables are:"+newline_indent+newline_indent.join(table_names)

for table_name in table_names:
    result = cur.execute("PRAGMA table_info('%s')" % table_name).fetchall()
    column_names = zip(*result)[1]
    print ("\ncolumn names for %s:" % table_name)+newline_indent+(newline_indent.join(column_names))

db.close()
print "\nexiting."

(编辑:我一直在对此进行定期投票,所以这是针对找到此答案的人的python3版本)

import sqlite3

db_filename = 'database.sqlite'
newline_indent = '\n   '

db=sqlite3.connect(db_filename)
db.text_factory = str
cur = db.cursor()

result = cur.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall()
table_names = sorted(list(zip(*result))[0])
print ("\ntables are:"+newline_indent+newline_indent.join(table_names))

for table_name in table_names:
    result = cur.execute("PRAGMA table_info('%s')" % table_name).fetchall()
    column_names = list(zip(*result))[1]
    print (("\ncolumn names for %s:" % table_name)
           +newline_indent
           +(newline_indent.join(column_names)))

db.close()
print ("\nexiting.")

Here’s a short and simple python program to print out the table names and the column names for those tables (python 2. python 3 follows).

import sqlite3

db_filename = 'database.sqlite'
newline_indent = '\n   '

db=sqlite3.connect(db_filename)
db.text_factory = str
cur = db.cursor()

result = cur.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall()
table_names = sorted(zip(*result)[0])
print "\ntables are:"+newline_indent+newline_indent.join(table_names)

for table_name in table_names:
    result = cur.execute("PRAGMA table_info('%s')" % table_name).fetchall()
    column_names = zip(*result)[1]
    print ("\ncolumn names for %s:" % table_name)+newline_indent+(newline_indent.join(column_names))

db.close()
print "\nexiting."

(EDIT: I have been getting periodic vote-ups on this, so here is the python3 version for people who are finding this answer)

import sqlite3

db_filename = 'database.sqlite'
newline_indent = '\n   '

db=sqlite3.connect(db_filename)
db.text_factory = str
cur = db.cursor()

result = cur.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall()
table_names = sorted(list(zip(*result))[0])
print ("\ntables are:"+newline_indent+newline_indent.join(table_names))

for table_name in table_names:
    result = cur.execute("PRAGMA table_info('%s')" % table_name).fetchall()
    column_names = list(zip(*result))[1]
    print (("\ncolumn names for %s:" % table_name)
           +newline_indent
           +(newline_indent.join(column_names)))

db.close()
print ("\nexiting.")

回答 5

显然,Python 2.6中包含的sqlite3版本具有此功能:http : //docs.python.org/dev/library/sqlite3.html

# Convert file existing_db.db to SQL dump file dump.sql
import sqlite3, os

con = sqlite3.connect('existing_db.db')
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write('%s\n' % line)

Apparently the version of sqlite3 included in Python 2.6 has this ability: http://docs.python.org/dev/library/sqlite3.html

# Convert file existing_db.db to SQL dump file dump.sql
import sqlite3, os

con = sqlite3.connect('existing_db.db')
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write('%s\n' % line)

回答 6

经过很多摆弄之后,我在sqlite文档中找到了一个更好的答案,它列出了表的元数据,甚至是附加的数据库。

meta = cursor.execute("PRAGMA table_info('Job')")
for r in meta:
    print r

关键信息是前缀table_info,而不是带有附件句柄名称的my_table。

After a lot of fiddling I found a better answer at sqlite docs for listing the metadata for the table, even attached databases.

meta = cursor.execute("PRAGMA table_info('Job')")
for r in meta:
    print r

The key information is to prefix table_info, not my_table with the attachment handle name.


回答 7

如果有人想对熊猫做同样的事情

import pandas as pd
import sqlite3
conn = sqlite3.connect("db.sqlite3")
table = pd.read_sql_query("SELECT name FROM sqlite_master WHERE type='table'", conn)
print(table)

If someone wants to do the same thing with Pandas

import pandas as pd
import sqlite3
conn = sqlite3.connect("db.sqlite3")
table = pd.read_sql_query("SELECT name FROM sqlite_master WHERE type='table'", conn)
print(table)

回答 8

这里查看转储。似乎在sqlite3库中有一个转储函数。

Check out here for dump. It seems there is a dump function in the library sqlite3.


回答 9

#!/usr/bin/env python
# -*- coding: utf-8 -*-

if __name__ == "__main__":

   import sqlite3

   dbname = './db/database.db'
   try:
      print "INITILIZATION..."
      con = sqlite3.connect(dbname)
      cursor = con.cursor()
      cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
      tables = cursor.fetchall()
      for tbl in tables:
         print "\n########  "+tbl[0]+"  ########"
         cursor.execute("SELECT * FROM "+tbl[0]+";")
         rows = cursor.fetchall()
         for row in rows:
            print row
      print(cursor.fetchall())
   except KeyboardInterrupt:
      print "\nClean Exit By user"
   finally:
      print "\nFinally"
#!/usr/bin/env python
# -*- coding: utf-8 -*-

if __name__ == "__main__":

   import sqlite3

   dbname = './db/database.db'
   try:
      print "INITILIZATION..."
      con = sqlite3.connect(dbname)
      cursor = con.cursor()
      cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
      tables = cursor.fetchall()
      for tbl in tables:
         print "\n########  "+tbl[0]+"  ########"
         cursor.execute("SELECT * FROM "+tbl[0]+";")
         rows = cursor.fetchall()
         for row in rows:
            print row
      print(cursor.fetchall())
   except KeyboardInterrupt:
      print "\nClean Exit By user"
   finally:
      print "\nFinally"

回答 10

我已经在PHP中实现了sqlite表架构解析器,您可以在此处检查:https : //github.com/c9s/LazyRecord/blob/master/src/LazyRecord/TableParser/SqliteTableDefinitionParser.php

您可以使用此定义解析器来解析如下代码所示的定义:

$parser = new SqliteTableDefinitionParser;
$parser->parseColumnDefinitions('x INTEGER PRIMARY KEY, y DOUBLE, z DATETIME default \'2011-11-10\', name VARCHAR(100)');

I’ve implemented a sqlite table schema parser in PHP, you may check here: https://github.com/c9s/LazyRecord/blob/master/src/LazyRecord/TableParser/SqliteTableDefinitionParser.php

You can use this definition parser to parse the definitions like the code below:

$parser = new SqliteTableDefinitionParser;
$parser->parseColumnDefinitions('x INTEGER PRIMARY KEY, y DOUBLE, z DATETIME default \'2011-11-10\', name VARCHAR(100)');

使用python向RESTful API发出请求

问题:使用python向RESTful API发出请求

我有一个RESTful API,我已经在EC2实例上使用Elasticsearch的实现公开了索引内容的语料库。我可以通过从终端机(MacOSX)运行以下命令来查询搜索:

curl -XGET 'http://ES_search_demo.com/document/record/_search?pretty=true' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'

如何使用python/requestspython/urllib2(不确定要使用哪一个-一直在使用urllib2,但听说请求更好……)将以上转换为API请求?我是否可以通过标题?

I have a RESTful API that I have exposed using an implementation of Elasticsearch on an EC2 instance to index a corpus of content. I can query the search by running the following from my terminal (MacOSX):

curl -XGET 'http://ES_search_demo.com/document/record/_search?pretty=true' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'

How do I turn above into a API request using python/requests or python/urllib2 (not sure which one to go for – have been using urllib2, but hear that requests is better…)? Do I pass as a header or otherwise?


回答 0

使用请求

import requests
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
data = '''{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'''
response = requests.post(url, data=data)

然后,根据您的API返回的响应类型,您可能需要查看response.textresponse.json()(或可能response.status_code先检查)。请参阅此处的快速入门文档,尤其是本节

Using requests:

import requests
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
data = '''{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'''
response = requests.post(url, data=data)

Depending on what kind of response your API returns, you will then probably want to look at response.text or response.json() (or possibly inspect response.status_code first). See the quickstart docs here, especially this section.


回答 1

使用请求json使其变得简单。

  1. 调用API
  2. 假设API返回JSON,请使用json.loads函数将JSON对象解析为Python dict
  3. 遍历字典以提取信息。

请求模块为您提供有用的功能,以循环执行成功和失败。

if(Response.ok):将帮助您确定API调用是否成功(响应代码-200)

Response.raise_for_status() 将帮助您获取从API返回的http代码。

以下是进行此类API调用的示例代码。也可以在github中找到。该代码假定该API使用摘要身份验证。您可以跳过此步骤,也可以使用其他适当的身份验证模块来验证调用API的客户端。

#Python 2.7.6
#RestfulClient.py

import requests
from requests.auth import HTTPDigestAuth
import json

# Replace with the correct URL
url = "http://api_url"

# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtime
myResponse = requests.get(url,auth=HTTPDigestAuth(raw_input("username: "), raw_input("Password: ")), verify=True)
#print (myResponse.status_code)

# For successful API call, response code will be 200 (OK)
if(myResponse.ok):

    # Loading the response data into a dict variable
    # json.loads takes in only binary or string variables so using content to fetch binary content
    # Loads (Load String) takes a Json file and converts into python data structure (dict or list, depending on JSON)
    jData = json.loads(myResponse.content)

    print("The response contains {0} properties".format(len(jData)))
    print("\n")
    for key in jData:
        print key + " : " + jData[key]
else:
  # If response code is not ok (200), print the resulting http error code with description
    myResponse.raise_for_status()

Using requests and json makes it simple.

  1. Call the API
  2. Assuming the API returns a JSON, parse the JSON object into a Python dict using json.loads function
  3. Loop through the dict to extract information.

Requests module provides you useful function to loop for success and failure.

if(Response.ok): will help help you determine if your API call is successful (Response code – 200)

Response.raise_for_status() will help you fetch the http code that is returned from the API.

Below is a sample code for making such API calls. Also can be found in github. The code assumes that the API makes use of digest authentication. You can either skip this or use other appropriate authentication modules to authenticate the client invoking the API.

#Python 2.7.6
#RestfulClient.py

import requests
from requests.auth import HTTPDigestAuth
import json

# Replace with the correct URL
url = "http://api_url"

# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtime
myResponse = requests.get(url,auth=HTTPDigestAuth(raw_input("username: "), raw_input("Password: ")), verify=True)
#print (myResponse.status_code)

# For successful API call, response code will be 200 (OK)
if(myResponse.ok):

    # Loading the response data into a dict variable
    # json.loads takes in only binary or string variables so using content to fetch binary content
    # Loads (Load String) takes a Json file and converts into python data structure (dict or list, depending on JSON)
    jData = json.loads(myResponse.content)

    print("The response contains {0} properties".format(len(jData)))
    print("\n")
    for key in jData:
        print key + " : " + jData[key]
else:
  # If response code is not ok (200), print the resulting http error code with description
    myResponse.raise_for_status()

回答 2

因此,您想在GET请求的主体中传递数据,最好在POST调用中进行。您可以通过同时使用两个请求来实现。

原始请求

GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1
Host: ES_search_demo.com
Content-Length: 183
User-Agent: python-requests/2.9.0
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate

{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

带请求的示例呼叫

import requests

def consumeGETRequestSync():
data = '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {"Accept": "application/json"}
# call get service with headers and params
response = requests.get(url,data = data)
print "code:"+ str(response.status_code)
print "******************"
print "headers:"+ str(response.headers)
print "******************"
print "content:"+ str(response.text)

consumeGETRequestSync()

So you want to pass data in body of a GET request, better would be to do it in POST call. You can achieve this by using both Requests.

Raw Request

GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1
Host: ES_search_demo.com
Content-Length: 183
User-Agent: python-requests/2.9.0
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate

{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

Sample call with Requests

import requests

def consumeGETRequestSync():
data = '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {"Accept": "application/json"}
# call get service with headers and params
response = requests.get(url,data = data)
print "code:"+ str(response.status_code)
print "******************"
print "headers:"+ str(response.headers)
print "******************"
print "content:"+ str(response.text)

consumeGETRequestSync()

回答 3

以下是在python-中执行其余api的程序

import requests
url = 'https://url'
data = '{  "platform": {    "login": {      "userName": "name",      "password": "pwd"    }  } }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
sid=response.json()['platform']['login']['sessionId']   //to extract the detail from response
print(response.text)
print(sid)

Below is the program to execute the rest api in python-

import requests
url = 'https://url'
data = '{  "platform": {    "login": {      "userName": "name",      "password": "pwd"    }  } }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
sid=response.json()['platform']['login']['sessionId']   //to extract the detail from response
print(response.text)
print(sid)

Http-prompt 构建在HTTPie之上的交互式命令行HTTP和API测试客户端,具有自动完成、语法突出显示等功能

JSONDecodeError:预期值:第1行第1列(字符0)

问题:JSONDecodeError:预期值:第1行第1列(字符0)

Expecting value: line 1 column 1 (char 0)尝试解码JSON 时出现错误。

我用于API调用的URL在浏览器中可以正常工作,但是通过curl请求完成时会出现此错误。以下是我用于curl请求的代码。

错误发生在 return simplejson.loads(response_json)

    response_json = self.web_fetch(url)
    response_json = response_json.decode('utf-8')
    return json.loads(response_json)


def web_fetch(self, url):
        buffer = StringIO()
        curl = pycurl.Curl()
        curl.setopt(curl.URL, url)
        curl.setopt(curl.TIMEOUT, self.timeout)
        curl.setopt(curl.WRITEFUNCTION, buffer.write)
        curl.perform()
        curl.close()
        response = buffer.getvalue().strip()
        return response

完整回溯:

追溯:

File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nab/Desktop/pricestore/pricemodels/views.py" in view_category
  620.     apicall=api.API().search_parts(category_id= str(categoryofpart.api_id), manufacturer = manufacturer, filter = filters, start=(catpage-1)*20, limit=20, sort_by='[["mpn","asc"]]')
File "/Users/nab/Desktop/pricestore/pricemodels/api.py" in search_parts
  176.         return simplejson.loads(response_json)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/__init__.py" in loads
  455.         return _default_decoder.decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in decode
  374.         obj, end = self.raw_decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in raw_decode
  393.         return self.scan_once(s, idx=_w(s, idx).end())

Exception Type: JSONDecodeError at /pricemodels/2/dir/
Exception Value: Expecting value: line 1 column 1 (char 0)

I am getting error Expecting value: line 1 column 1 (char 0) when trying to decode JSON.

The URL I use for the API call works fine in the browser, but gives this error when done through a curl request. The following is the code I use for the curl request.

The error happens at return simplejson.loads(response_json)

    response_json = self.web_fetch(url)
    response_json = response_json.decode('utf-8')
    return json.loads(response_json)


def web_fetch(self, url):
        buffer = StringIO()
        curl = pycurl.Curl()
        curl.setopt(curl.URL, url)
        curl.setopt(curl.TIMEOUT, self.timeout)
        curl.setopt(curl.WRITEFUNCTION, buffer.write)
        curl.perform()
        curl.close()
        response = buffer.getvalue().strip()
        return response

Full Traceback:

Traceback:

File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nab/Desktop/pricestore/pricemodels/views.py" in view_category
  620.     apicall=api.API().search_parts(category_id= str(categoryofpart.api_id), manufacturer = manufacturer, filter = filters, start=(catpage-1)*20, limit=20, sort_by='[["mpn","asc"]]')
File "/Users/nab/Desktop/pricestore/pricemodels/api.py" in search_parts
  176.         return simplejson.loads(response_json)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/__init__.py" in loads
  455.         return _default_decoder.decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in decode
  374.         obj, end = self.raw_decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in raw_decode
  393.         return self.scan_once(s, idx=_w(s, idx).end())

Exception Type: JSONDecodeError at /pricemodels/2/dir/
Exception Value: Expecting value: line 1 column 1 (char 0)

回答 0

总结评论中的对话:

  • 无需使用simplejson库,Python作为json模块包含了相同的库。

  • 无需解码UTF8对unicode的响应,simplejson/ json .loads()方法可以本地处理UTF8编码的数据。

  • pycurl有一个非常古老的API。除非您有特定的使用要求,否则会有更好的选择。

requests提供最友好的API,包括JSON支持。如果可以,将您的通话替换为:

import requests

return requests.get(url).json()

To summarize the conversation in the comments:

  • There is no need to use simplejson library, the same library is included with Python as the json module.

  • There is no need to decode a response from UTF8 to unicode, the simplejson / json .loads() method can handle UTF8 encoded data natively.

  • pycurl has a very archaic API. Unless you have a specific requirement for using it, there are better choices.

requests offers the most friendly API, including JSON support. If you can, replace your call with:

import requests

return requests.get(url).json()

回答 1

检查响应数据主体,是否存在实际数据并且数据转储的格式是否正确。

在大多数情况下,您的json.loadsJSONDecodeError: Expecting value: line 1 column 1 (char 0)错误是由于:

  • 非JSON引用
  • XML / HTML输出(即以<开头的字符串),或
  • 不兼容的字符编码

最终,错误告诉您字符串在第一位置已经不符合JSON。

这样,如果尽管乍一看具有看起来像JSON的数据主体,但解析仍然失败,请尝试替换数据主体的引号:

import sys, json
struct = {}
try:
  try: #try parsing to dict
    dataform = str(response_json).strip("'<>() ").replace('\'', '\"')
    struct = json.loads(dataform)
  except:
    print repr(resonse_json)
    print sys.exc_info()

注意:数据中的引号必须正确转义

Check the response data-body, whether actual data is present and a data-dump appears to be well-formatted.

In most cases your json.loadsJSONDecodeError: Expecting value: line 1 column 1 (char 0) error is due to :

  • non-JSON conforming quoting
  • XML/HTML output (that is, a string starting with <), or
  • incompatible character encoding

Ultimately the error tells you that at the very first position the string already doesn’t conform to JSON.

As such, if parsing fails despite having a data-body that looks JSON like at first glance, try replacing the quotes of the data-body:

import sys, json
struct = {}
try:
  try: #try parsing to dict
    dataform = str(response_json).strip("'<>() ").replace('\'', '\"')
    struct = json.loads(dataform)
  except:
    print repr(resonse_json)
    print sys.exc_info()

Note: Quotes within the data must be properly escaped


回答 2

当您有一个HTTP错误代码(例如404)并尝试将响应解析为JSON时,使用requestslib JSONDecodeError可能会发生!

您必须首先检查200(OK)或让它出现错误以避免这种情况。我希望它以较少的错误消息失败。

注意:就像注释中提到的Martijn Pieters一样,如果发生错误(取决于实现),服务器可以使用JSON进行响应,因此检查Content-Type标头更加可靠。

With the requests lib JSONDecodeError can happen when you have an http error code like 404 and try to parse the response as JSON !

You must first check for 200 (OK) or let it raise on error to avoid this case. I wish it failed with a less cryptic error message.

NOTE: as Martijn Pieters stated in the comments servers can respond with JSON in case of errors (it depends on the implementation), so checking the Content-Type header is more reliable.


回答 3

我认为值得一提的是,在您解析JSON文件本身的内容时-健全性检查对于确保您实际上在调用文件json.loads()内容(而不是该JSON 的文件路径)非常有用。:

json_file_path = "/path/to/example.json"

with open(json_file_path, 'r') as j:
     contents = json.loads(j.read())

我有些尴尬地承认有时会发生这种情况:

contents = json.loads(json_file_path)

I think it’s worth mentioning that in cases where you’re parsing the contents of a JSON file itself – sanity checks can be useful to ensure that you’re actually invoking json.loads() on the contents of the file, as opposed to the file path of that JSON:

json_file_path = "/path/to/example.json"

with open(json_file_path, 'r') as j:
     contents = json.loads(j.read())

I’m a little embarrassed to admit that this can happen sometimes:

contents = json.loads(json_file_path)

回答 4

检查文件的编码格式,并在读取文件时使用相应的编码格式。它将解决您的问题。

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)

Check encoding format of your file and use corresponding encoding format while reading file. It will solve your problem.

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)

回答 5

很多时候,这是因为您要解析的字符串为空:

>>> import json
>>> x = json.loads("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

您可以通过json_string事先检查是否为空来进行补救:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}

A lot of times, this will be because the string you’re trying to parse is blank:

>>> import json
>>> x = json.loads("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

You can remedy by checking whether json_string is empty beforehand:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}

回答 6

即使调用了decode(),也可能嵌入了0。使用replace():

import json
struct = {}
try:
    response_json = response_json.decode('utf-8').replace('\0', '')
    struct = json.loads(response_json)
except:
    print('bad json: ', response_json)
return struct

There may be embedded 0’s, even after calling decode(). Use replace():

import json
struct = {}
try:
    response_json = response_json.decode('utf-8').replace('\0', '')
    struct = json.loads(response_json)
except:
    print('bad json: ', response_json)
return struct

回答 7

使用请求,我遇到了这个问题。感谢Christophe Roussy的解释。

为了调试,我使用了:

response = requests.get(url)
logger.info(type(response))

我从API返回了404响应。

I had exactly this issue using requests. Thanks to Christophe Roussy for his explanation.

To debug, I used:

response = requests.get(url)
logger.info(type(response))

I was getting a 404 response back from the API.


回答 8

我在请求(python库)时遇到了同样的问题。它恰好是accept-encoding标题。

它是这样设置的: 'accept-encoding': 'gzip, deflate, br'

我只是将其从请求中删除,并停止获取错误。

I was having the same problem with requests (the python library). It happened to be the accept-encoding header.

It was set this way: 'accept-encoding': 'gzip, deflate, br'

I simply removed it from the request and stopped getting the error.


回答 9

对我来说,它没有在请求中使用身份验证。

For me, it was not using authentication in the request.


回答 10

对我来说,这是服务器响应而不是200响应,并且响应不是json格式的。我最终在json解析之前执行了此操作:

# this is the https request for data in json format
response_json = requests.get() 

# only proceed if I have a 200 response which is saved in status_code
if (response_json.status_code == 200):  
     response = response_json.json() #converting from json to dictionary using json library

For me it was server responding with something other than 200 and the response was not json formatted. I ended up doing this before the json parse:

# this is the https request for data in json format
response_json = requests.get() 

# only proceed if I have a 200 response which is saved in status_code
if (response_json.status_code == 200):  
     response = response_json.json() #converting from json to dictionary using json library

回答 11

如果您是Windows用户,则Tweepy API可以在数据对象之间生成一个空行。由于这种情况,您会收到“ JSONDecodeError:预期值:第1行第1列(字符0)”错误。为避免此错误,您可以删除空行。

例如:

 def on_data(self, data):
        try:
            with open('sentiment.json', 'a', newline='\n') as f:
                f.write(data)
                return True
        except BaseException as e:
            print("Error on_data: %s" % str(e))
        return True

参考: Twitter流API从None给出JSONDecodeError(“ Expecting value”,s,err.value)

If you are a Windows user, Tweepy API can generate an empty line between data objects. Because of this situation, you can get “JSONDecodeError: Expecting value: line 1 column 1 (char 0)” error. To avoid this error, you can delete empty lines.

For example:

 def on_data(self, data):
        try:
            with open('sentiment.json', 'a', newline='\n') as f:
                f.write(data)
                return True
        except BaseException as e:
            print("Error on_data: %s" % str(e))
        return True

Reference: Twitter stream API gives JSONDecodeError(“Expecting value”, s, err.value) from None


回答 12

只需检查请求的状态码是否为200。例如:

if status != 200:
    print("An error has occured. [Status code", status, "]")
else:
    data = response.json() #Only convert to Json when status is OK.
    if not data["elements"]:
        print("Empty JSON")
    else:
        "You can extract data here"

Just check if the request has a status code 200. So for example:

if status != 200:
    print("An error has occured. [Status code", status, "]")
else:
    data = response.json() #Only convert to Json when status is OK.
    if not data["elements"]:
        print("Empty JSON")
    else:
        "You can extract data here"

回答 13

我在基于Python的Web API的响应中收到了这样的错误.text,但是它导致了我的到来,因此这可能会帮助遇到类似问题的其他人(使用requests.. 过滤响应并在搜索中请求问题非常困难)

使用json.dumps()要求 data ARG创建JSON的正确转义的字符串前发布解决了该问题对我来说

requests.post(url, data=json.dumps(data))

I received such an error in a Python-based web API’s response .text, but it led me here, so this may help others with a similar issue (it’s very difficult to filter response and request issues in a search when using requests..)

Using json.dumps() on the request data arg to create a correctly-escaped string of JSON before POSTing fixed the issue for me

requests.post(url, data=json.dumps(data))

Django-rest-framework 一个强大而灵活的Django WebAPI的工具包

概述

DjangoREST框架是一个强大而灵活的构建WebAPI的工具包

您可能希望使用睡觉框架的一些原因:

有一个用于测试目的的实时示例API,available here

下面来自可浏览API的屏幕截图


要求

  • Python(3.5、3.6、3.7、3.8、3.9)
  • Django(2.2,3.0,3.1,3.2)

我们强烈推荐并且仅官方支持每个Python和Django系列的最新补丁版本

安装

使用以下方式安装pip

pip install djangorestframework

添加'rest_framework'致您的INSTALLED_APPS设置

INSTALLED_APPS = [
    ...
    'rest_framework',
]

示例

让我们来看一个使用睡觉框架构建用于访问用户和组的简单模型支持的应用编程接口的快速示例

像这样启动一个新项目

pip install django
pip install djangorestframework
django-admin startproject example .
./manage.py migrate
./manage.py createsuperuser

现在编辑example/urls.py项目中的模块:

from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers

# Serializers define the API representation.
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'is_staff']


# ViewSets define the view behavior.
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


# Routers provide a way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)


# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

我们还想为我们的API配置几个设置

将以下内容添加到您的settings.py模块:

INSTALLED_APPS = [
    ...  # Make sure to include the default installed apps here.
    'rest_framework',
]

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
    ]
}

就这样,我们完了!

./manage.py runserver

现在,您可以在浏览器中打开API,地址为http://127.0.0.1:8000/,并查看新的“用户”API。如果您使用Login控件,您还可以在系统中添加、创建和删除用户

您还可以使用命令行工具与API交互,例如curl例如,要列出用户端点,请执行以下操作:

$ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
[
    {
        "url": "http://127.0.0.1:8000/users/1/",
        "username": "admin",
        "email": "admin@example.com",
        "is_staff": true,
    }
]

或创建新用户:

$ curl -X POST -d username=new -d email=new@example.com -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
{
    "url": "http://127.0.0.1:8000/users/2/",
    "username": "new",
    "email": "new@example.com",
    "is_staff": false,
}

文档和支持

有关该项目的完整文档,请访问https://www.django-rest-framework.org/

有关问题和支持,请使用REST framework discussion group,或#restframework关于Freenode IRC

您可能还想要follow the author on Twitter

安全性

请参阅security policy

Fastapi-FastAPI框架,高性能,易学,编码速度快,可投入生产

FastAPI框架,高性能,易学,编码速度快,可投入生产


文档https://fastapi.tiangolo.com

源代码https://github.com/tiangolo/fastapi


FastAPI是一种现代、快速(高性能)的Web框架,用于使用Python 3.6+基于标准Python类型提示构建API

主要功能包括:

  • 快地:非常高的性能,可与节点JS(多亏了斯塔莱特和皮丹蒂克)One of the fastest Python frameworks available
  • 快速编码:提高功能开发速度约200%至300%。*
  • 更少的错误:减少约40%的人为(开发人员)引起的错误。*
  • 直观:强大的编辑支持。无处不在的完成度。调试时间更短
  • 简单易懂:设计成易于使用和学习。减少阅读文档的时间
  • 短的:最大限度地减少代码重复。来自每个参数声明的多个功能。更少的错误
  • 健壮:获取可投入生产的代码。使用自动交互文档
  • 基于标准的:基于(并完全兼容)API开放标准:OpenAPI(以前称为Swagger)和JSON Schema

*基于对内部开发团队、构建生产应用程序的测试进行估计

意见

[.]我在用FastAPI这几天有一吨多。[.]实际上我正计划把它用在我所有团队的微软的ML服务他们中的一些人正在融入核心窗口产品和一些办公室产品

卡比尔汗-微软(ref)

我们采用了FastAPI库以派生睡觉可以查询获取的服务器预测[路德维希]

皮耶罗·莫利诺,雅罗斯拉夫·杜丁和赛苏曼斯·米利亚拉-优步(Uber)(ref)

Netflix我很高兴地宣布我们的危机管理编排框架:派单好了![使用以下组件构建FastAPI]

凯文·格利森,马克·维拉诺瓦,福里斯特·蒙森-Netflix(ref)

我欣喜若狂FastAPI太好玩了!

布莱恩·奥肯-Python Bytes播客主持人(ref)

老实说,你建造的东西看起来非常坚固和精美。在很多方面,这是我想要的拥抱一下是-看到有人建造这样的建筑真的很鼓舞人心

蒂莫西·克罗斯利-Hug创建者(ref)

如果你想学一门现代框架要构建睡觉API,请查看FastAPI[.]它快速、易用、易学。

我们已经切换到FastAPI为了我们的API接口[.]我想你会喜欢的。

Ines Montani-Matthew Honnibal-Explosion AI创始人-spaCy创作者(ref)(ref)

要求

Python 3.6+

FastAPI站在巨人的肩膀上:

安装

$ pip install fastapi

---> 100%

您还需要一台ASGI服务器用于生产,例如UvicornHypercorn

$ pip install uvicorn[standard]

---> 100%

示例

创建它

  • 创建文件main.py使用:
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}
或使用async def

如果您的代码使用async/await,使用async def

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

注意事项

如果您不知道,请查看“赶时间?”部分关于async and await in the docs

运行它

使用以下命令运行服务器:

$ uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
关于命令uvicorn main:app --reload

该命令uvicorn main:app指的是:

  • main:文件main.py(Python“模块”)
  • app:在中创建的对象main.py用这条线app = FastAPI()
  • --reload:使服务器在代码更改后重新启动。这样做只是为了发展。

检查一下

在以下位置打开您的浏览器http://127.0.0.1:8000/items/5?q=somequery

您将看到JSON响应为:

{"item_id": 5, "q": "somequery"}

您已经创建了一个API,该API:

  • 中接收HTTP请求。路径//items/{item_id}
  • 两者都有路径拿走GET运营(也称为HTTP方法:)
  • 这个路径/items/{item_id}有一个路径参数item_id这应该是一个int
  • 这个路径/items/{item_id}有一个可选的str查询参数q

交互式API文档

现在转到http://127.0.0.1:8000/docs

您将看到自动交互API文档(由提供Swagger UI):

替代API文档

现在,请转到http://127.0.0.1:8000/redoc

您将看到替代自动文档(由提供ReDoc):

示例升级

现在修改该文件main.py接收来自PUT请求

使用标准Python类型声明Body,这要归功于Pydatics

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}


@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}

服务器应自动重新加载(因为您添加了--reload发送到uvicorn上述命令)

Interactive API文档升级

现在转到http://127.0.0.1:8000/docs

  • 交互API文档将自动更新,包括新的Body:

  • 点击[试用]按钮,即可填写参数,直接与接口交互:

  • 然后点击“执行”按钮,用户界面将与您的API进行通信,发送参数,得到结果并显示在屏幕上:

备用API文档升级

现在,请转到http://127.0.0.1:8000/redoc

  • 替代文档还将反映新的查询参数和正文:

概述

总而言之,您声明一次作为函数参数的参数类型、正文等

您可以使用标准的现代Python类型来实现这一点

您不必学习新语法、特定库的方法或类等

只是标准的Python 3.6+

例如,对于int

item_id: int

或者对于更复杂的Item型号:

item: Item

有了这一份声明,你就会得到:

  • 编辑器支持,包括:
    • 完成
    • 类型检查
  • 数据验证:
    • 数据无效时自动清除错误
    • 即使是针对深度嵌套的JSON对象的验证也是如此
  • 输入数据的转换:从网络到Python数据和类型的转换。阅读自:
    • JSON
    • 路径参数
    • 查询参数
    • 曲奇饼
    • 标题
    • 表格
    • 文件
  • 输出数据转换:从Python数据和类型转换为网络数据(如JSON):
    • 转换Python类型(strintfloatboollist等)
    • datetime对象
    • UUID对象
    • 数据库模型
    • 还有更多
  • 自动交互式API文档,包括2个替代用户界面:
    • 大摇大摆的UI
    • 复单

回到前面的代码示例,FastAPI将:

  • 验证是否存在item_id在用于的路径中GETPUT请求
  • 验证item_id类型为intGETPUT请求
    • 如果不是,客户端将看到一个有用的、明确的错误
  • 检查是否存在名为的可选查询参数q(如图所示http://127.0.0.1:8000/items/foo?q=somequery)用于GET请求
    • 作为q参数是用= None,它是可选的
    • 如果没有None这将是必需的(就像在具有以下情况的情况下的身体一样PUT)
  • PUT请求/items/{item_id},将正文读作JSON:
    • 检查它是否具有必需的属性name这应该是一个str
    • 检查它是否具有必需的属性price那一定是一个float
    • 检查它是否具有可选属性is_offer,那应该是一个bool,如果存在
    • 所有这些也适用于深度嵌套的JSON对象
  • 自动从JSON转换为JSON或自动转换为JSON
  • 使用OpenAPI记录可由以下人员使用的所有内容:
    • 交互式文档系统
    • 自动客户端代码生成系统,适用于多种语言
  • 直接提供2个交互式文档web界面

我们只是触及了皮毛,但您已经对它的工作原理有了大致的了解

尝试使用以下命令更改行:

    return {"item_name": item.name, "item_id": item_id}

出发地:

        ... "item_name": item.name ...

收件人:

        ... "item_price": item.price ...

并查看您的编辑器将如何自动完成属性并了解其类型:

有关包含更多功能的更完整示例,请参阅Tutorial – User Guide

剧透警报:教程-用户指南包括:

  • 的声明参数从其他不同的地方,如:标题曲奇饼表单域文件
  • 如何设置验证约束作为maximum_lengthregex
  • 一款功能非常强大且易于使用的依赖项注入系统
  • 安全性和身份验证,包括支持OAuth2使用JWT代币HTTP Basic身份验证
  • 更高级(但同样简单)的声明技术深度嵌套的JSON模型(多亏了皮丹蒂克)
  • 许多额外功能(感谢Starlette),如:
    • WebSockets
    • 图形QL
    • 极其简单的测试,基于requestspytest
    • CORS
    • Cookie会话
    • 还有更多

性能

独立TechEmpower基准显示FastAPI在Uvicorn AS下运行的应用程序one of the fastest Python frameworks available,仅低于Starlette和Uvicorn本身(由FastAPI内部使用)。(*)

要了解更多信息,请参阅小节Benchmarks

可选依赖项

由Pydtic使用:

由Starlette使用:

  • requests-如果要使用TestClient
  • aiofiles-如果要使用,则为必填项FileResponseStaticFiles
  • jinja2-如果要使用默认模板配置,则为必填项
  • python-multipart-如果您想支持表单“解析”,则为必填项,带有request.form()
  • itsdangerous-需要用于SessionMiddleware支持
  • pyyaml-Starlette的必填项SchemaGenerator支持(FastAPI可能不需要)
  • graphene-需要用于GraphQLApp支持
  • ujson-如果要使用,则为必填项UJSONResponse

由FastAPI/Starlette使用:

  • uvicorn-对于加载和服务您的应用程序的服务器
  • orjson-如果要使用,则为必填项ORJSONResponse

您可以使用以下命令安装所有这些组件pip install fastapi[all]

许可证

这个项目是根据麻省理工学院的许可条款授权的。