简体   繁体   English

用Python构建API调用

[英]Structuring API Calls in Python

I'm having difficulty in determining what the best practices are for structuring data for calling various APIs that contain bitcoin prices. 我在确定用于构造数据以调用包含比特币价格的各种API的最佳实践方面遇到困难。 I want to be able to call multiple APIs, without duplicate code. 我希望能够调用多个API,而无需重复代码。

My initial thought was to build classes for each of the APIs I would be calling, and feed their attributes (api_id, url, and json_tree (json path I'd like to pull data from) to the BtcAPI class, and spit them out. 我最初的想法是为要调用的每个API构建类,并将其属性(api_id,url和json_tree(我想从中提取数据的json路径)提供给BtcAPI类,然后将其吐出。

*Note, before reading that while BtcAPI works, the Coindesk/Bitstamp classes do not yet interact with that class. *请注意,阅读,虽然BtcAPI工作时,Coindesk / Bitstamp类还没有与类交互之前。 I want to ask about the way I should do this before I go to the trouble...* 我想问一下在麻烦之前我该怎么做... *

Now, I'm wondering if I shouldn't make them lists, like: 现在,我想知道是否不应该将它们列出,例如:

coindesk = ['http://www.something.com', 'coindesk', '["time"]["updated"]']

...and just iterate through each of them. ...然后遍历每个对象。 Or dicts, or any variety of other thing. 或字典,或其他各种东西。 What data structure is indicated here? 这里显示什么数据结构?

I am basically looking for a bit of a code review (since this code isn't working, I don't want to send it to the code review stack) and an understanding of best practices: tell me where you think I'm screwing up horribly, and what I can do to structure this data better? 我基本上是在寻找一些代码审查(因为此代码无法正常工作,所以我不想将其发送到代码审查堆栈),并且了解最佳做法:告诉我您认为我在搞砸的地方可怕地上升,我该怎么做才能更好地构造这些数据? I'm a python and oop noob. 我是python和oop noob。 I could do this procedurally, but it would be ugly and superfluous. 我可以按程序进行此操作,但这将是丑陋且多余的。 I imagine I'm using classes a bit wrong, too. 我想我也使用了一些错误的类。 Insights? 有见识? Help? 救命? Thank you! 谢谢!

Thank you! 谢谢!

import json
import urllib.request

#The BtcAPI class works well when you feed it static variables. It returns json.

class BtcAPI:

    def __init__(self, url, api_id):
        self.url = url
        self.api_id = api_id

    def btc_api_call(self):

        hdr = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'     }
        req = urllib.request.Request(url, headers=hdr)
        readdata = urllib.request.urlopen(req)
        json_data = readdata.read()

        json_dict = json.loads(json_data)
        return(json_dict)

class Coindesk:


    api_id = 'Coindesk'
    url = 'https://api.coindesk.com/v1/bpi/currentprice.json'               
    json_tree = json_dict['time']['updated']

    def __init__(self):

        self.current_us_price = current_us_price

class Bitstamp:


    api_id = 'Bitstamp'
    url = 'https://www.bitstamp.net/api/ticker/'               
    json_tree = json_dict['last']

    def __init__(self):

        self.current_us_price = current_us_price

coindesk_url = Coindesk()
coindeskoutput = coindesk_url.url
print(coindeskoutput)

If you want a generic piece of code, I would suggest that you dissociate your code and your configuration data into 2 files. 如果您需要通用代码,建议您将代码和配置数据分解为2个文件。 This way you can manage your configuration data (URL, JSON attributes you want to retrieve) without having to modify your actual Python code. 这样,您可以管理配置数据(URL,要检索的JSON属性),而无需修改实际的Python代码。 This is usually considered a good practice but it implies to manage two files instead of one so it can be a bit of a burden if you are on a very small project. 通常认为这是一种好习惯,但是它意味着要管理两个文件而不是一个文件,因此如果您的项目很小,则可能会有些负担。

Example in your case, you can have: 以您的情况为例,您可以:

  • conf.ini conf.ini
  • bitcoin_api.py bitcoin_api.py

conf.ini conf.ini

Configuration file which would look like this: 配置文件如下所示:

[COINDESK]
url: https://api.coindesk.com/v1/bpi/currentprice.json
response: time.updated

[BITSTAMP]
url: https://www.bitstamp.net/api/ticker
response: last

bitcoin_api.py bitcoin_api.py

Your code would look like this: 您的代码如下所示:

import configparser
import requests
import os


class BitcoinAPI:
    def __init__(self, API):
        config = configparser.ConfigParser()
        config.read(os.path.dirname(__file__) + '/conf.ini')
        self.url = config.get(API, 'url')
        self.attribute = config.get(API, 'response')
        self.header = {'content-type': 'application/json'}

    def get(self):
        response = requests.get(self.url, headers=self.header)
        response = response.json()

        # Browse the response to fetch only the attributes you want
        self.attribute = self.attribute.split('.')
        depth = len(self.attribute)
        for i in range(depth):
            response = response[self.attribute[i]]

        print(response)
        return response

Then you can call you class in your main script: 然后,您可以在主脚本中调用类:

import bitcoin_api
result = bitcoin_api.BitcoinAPI('COINDESK').get()
result = bitcoin_api.BitcoinAPI('BITSTAMP').get()

Well, the sane way to struct your code would involve super classes (inheritance) and some sort of standardisation (interfaces). 好吧,构造代码的明智方法将涉及超类(继承)和某种标准化(接口)。

Assuming that I understand you question, you need a standard on how to request the prices from various exchanges. 假设我理解您的问题,那么您需要一个有关如何从各个交易所索取价格的标准。

So consider this structure (of course it's completely draft): 因此,请考虑以下结构(当然,它是完全草稿的):

import requests

class BitcoinAPI:

    def get_price_usd(self):
        raise NotImplementedError

    @staticmethod
    def generic_unothorized_request(request_method, url, **kwargs):
        return getattr(requests, request_method)(url, **kwargs)


class CoinDesk(BitcoinAPI):

    url = 'https://api.coindesk.com/v1/bpi/currentprice.json'

    def get_price_usd(self):
        return self.generic_unothorized_request('get', url)
        # process result, bla bla


class Bitstamp(BitcoinAPI):

    def get_price_usd(self):
        # Implementation of get_price_usd for Bitstamp
        return 0.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM