ความแตกต่างใน boto3 ระหว่างทรัพยากรไคลเอ็นต์และเซสชันหรือไม่


216

ฉันใช้ Python 2.7.12 ใน Ubuntu 16.04 LTS ฉันเรียนรู้วิธีการใช้ boto3 จากลิงค์ต่อไปนี้: https://boto3.readthedocs.io/en/latest/guide/quickstart.html#using-boto-3 ข้อสงสัยของฉันคือเมื่อใช้ทรัพยากรลูกค้าหรือเซสชันและหน้าที่การใช้งานของพวกเขา

คำตอบ:


248

นี่คือบางส่วนข้อมูลรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่ไคลเอนต์ , ทรัพยากรและเซสชันเป็นทั้งหมดที่เกี่ยวกับ

ลูกค้า:

  • การเข้าถึงบริการ AWS ระดับต่ำ
  • สร้างจากคำอธิบายบริการของ AWS
  • exposes botocore client ให้กับผู้พัฒนา
  • โดยทั่วไปแผนที่ 1: 1 กับ API บริการ AWS
  • การดำเนินการบริการ AWS ทั้งหมดได้รับการสนับสนุนจากลูกค้า
  • ชื่อวิธีการใส่งู (เช่น ListBuckets API => วิธี list_buckets)

นี่คือตัวอย่างของการเข้าถึงระดับไคลเอนต์สำหรับออบเจ็กต์ S3 ของถัง (สูงสุด 1,000 **):

import boto3

client = boto3.client('s3')
response = client.list_objects_v2(Bucket='mybucket')
for content in response['Contents']:
    obj_dict = client.get_object(Bucket='mybucket', Key=content['Key'])
    print(content['Key'], obj_dict['LastModified'])

** คุณจะต้องใช้paginatorหรือใช้ลูปของคุณเองเรียก list_objects () ซ้ำ ๆ ด้วยเครื่องหมายต่อเนื่องหากมีมากกว่า 1,000

ทรัพยากร:

  • API ระดับสูงกว่าเชิงวัตถุ
  • สร้างขึ้นจากคำอธิบายทรัพยากร
  • ใช้ตัวระบุและคุณสมบัติ
  • มีการกระทำ (การดำเนินการกับทรัพยากร)
  • เปิดเผยทรัพยากรย่อยและการเก็บรวบรวมทรัพยากร AWS
  • ไม่ได้ให้ความคุ้มครอง API 100% ของบริการ AWS

นี่คือตัวอย่างที่เทียบเท่าโดยใช้การเข้าถึงระดับทรัพยากรไปยังวัตถุของที่เก็บข้อมูล S3 (ทั้งหมด):

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
for obj in bucket.objects.all():
    print(obj.key, obj.last_modified)

โปรดทราบว่าในกรณีนี้คุณไม่จำเป็นต้องทำการเรียก API ครั้งที่สองเพื่อรับวัตถุ พวกเขาพร้อมให้คุณใช้เป็นคอลเล็กชันบนที่เก็บข้อมูล คอลเลกชันของแหล่งข้อมูลย่อยเหล่านี้โหลดอย่างเกียจคร้าน

คุณจะเห็นว่าResourceรุ่นของรหัสนั้นง่ายกว่ากะทัดรัดกว่าและมีความสามารถมากขึ้น Clientรุ่นของรหัสที่จริงจะมีความซับซ้อนมากขึ้นกว่าที่แสดงไว้ข้างต้นถ้าคุณต้องการที่จะรวมเลขหน้า

เซสชั่น:

  • เก็บข้อมูลการกำหนดค่า (ข้อมูลรับรองเบื้องต้นและภูมิภาคที่เลือก)
  • ช่วยให้คุณสร้างลูกค้าบริการและทรัพยากร
  • boto3 สร้างเซสชันเริ่มต้นสำหรับคุณเมื่อจำเป็น

ทรัพยากรที่มีประโยชน์เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับแนวคิด boto3 เหล่านี้เป็นอีกครั้งเบื้องต้น: Invent วิดีโอ


2
มีความแตกต่างด้านประสิทธิภาพระหว่างไคลเอนต์และทรัพยากรหรือไม่ ฉันมีปัญหานี้ซึ่งการลบข้อความออกจากคิว sqs นั้นเร็วขึ้นโดยใช้ไคลเอนต์และช้ากว่าการใช้ทรัพยากร
Vaulstein

3
@Vaulstein ฉันไม่มีการเปรียบเทียบที่เฉพาะเจาะจงใด ๆ ที่จะแบ่งปัน แต่โดยทั่วไปฉันคาดหวังว่าส่วนต่อประสานกับไคลเอ็นต์จะเบากว่าทรัพยากรและอาจจะเร็วกว่าในขณะใช้งานจริง
jarmod

@jarmod ในฐานะส่วนหนึ่งของการเรียนรู้ฉันได้ลองสร้าง S3 bucket โดยใช้ทั้งสองวิธี ฉันรู้สึกว่าการสร้างทรัพยากรจะเกิดขึ้นเร็วขึ้นเมื่อใช้ "ลูกค้า" เทียบกับ "ทรัพยากร" ถูกต้องหรือไม่ ถ้าใช่ทำไมการสร้างทรัพยากรถึงเร็วกว่าด้วยไคลเอนต์
Saravanan G

1
@SaravananG หากคุณs3.set_stream_logger('botocore')คุณสามารถดูบันทึกของการเขียนโปรแกรมเมตาที่ boto3 (การโทรเข้าสู่ botocore) จะอยู่ภายใต้ฮูด มันทำงานได้ดังนั้นคุณไม่จำเป็นต้อง มันมีระบบเหตุการณ์ทั้งหมดสำหรับการปรับแต่ง / ความสามารถในการเสียบและ 3 (+?) อนุกรมวิธานเชิงลึกของเหตุการณ์เพื่อจัดการการเตรียมคำขอการแยกวิเคราะห์การตอบสนอง การสร้างพารามิเตอร์, การลงนามคำขอ, การตรวจจับภูมิภาคเป็นสิ่งสำคัญ FYI มันเป็นความเจ็บปวดที่วิเศษในการปรับเปลี่ยน ดูการเปลี่ยนแปลงง่าย
mcint

89

ฉันจะพยายามอธิบายให้ง่ายที่สุด ดังนั้นจึงไม่มีการรับประกันความถูกต้องของข้อกำหนดจริง

เซสชันคือจุดเริ่มต้นการเชื่อมต่อกับบริการ AWS เช่นต่อไปนี้เป็นเซสชันเริ่มต้นที่ใช้โปรไฟล์ข้อมูลรับรองเริ่มต้น (เช่น ~ / .aws / หนังสือรับรองหรือถือว่า EC2 ของคุณใช้โปรไฟล์อินสแตนซ์ IAM)

sqs = boto3.client('sqs')
s3 = boto3.resource('s3')

เนื่องจากเซสชันเริ่มต้นถูก จำกัด เฉพาะโปรไฟล์หรือโปรไฟล์ที่ใช้บางครั้งคุณจำเป็นต้องใช้เซสชันที่กำหนดเองเพื่อแทนที่การกำหนดค่าเซสชันเริ่มต้น (เช่น region_name, endpoint_url ฯลฯ ) เช่น

# custom resource session must use boto3.Session to do the override
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_session = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource('s3')
video_s3 = my_east_session.resource('s3')

# you have two choices of create custom client session. 
backup_s3c = my_west_session.client('s3')
video_s3c = boto3.client("s3", region_name = 'us-east-1')

ทรัพยากร : นี่คือระดับบริการระดับสูงที่แนะนำให้ใช้ สิ่งนี้จะช่วยให้คุณเชื่อมโยงทรัพยากร AWS เฉพาะและผ่านไปได้ดังนั้นคุณจึงใช้สิ่งที่เป็นนามธรรมมากกว่ากังวลว่าบริการเป้าหมายใดที่ชี้ไป เมื่อคุณสังเกตเห็นจากส่วนเซสชั่นถ้าคุณมีเซสชั่นที่กำหนดเองคุณเพียงผ่านวัตถุนามธรรมนี้กว่ากังวลเกี่ยวกับภูมิภาคที่กำหนดเองทั้งหมดและอื่น ๆ ที่จะผ่านไป ต่อไปนี้เป็นตัวอย่างที่ซับซ้อนเช่น

import boto3 
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_session = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource("s3")
video_s3 = my_east_session.resource("s3")
backup_bucket = backup_s3.Bucket('backupbucket') 
video_bucket = video_s3.Bucket('videobucket')

# just pass the instantiated bucket object
def list_bucket_contents(bucket):
   for object in bucket.objects.all():
      print(object.key)

list_bucket_contents(backup_bucket)
list_bucket_contents(video_bucket)

ไคลเอนต์เป็นวัตถุระดับต่ำ สำหรับการโทรของลูกค้าแต่ละครั้งคุณจะต้องระบุทรัพยากรการกำหนดเป้าหมายอย่างชัดเจนชื่อเป้าหมายของบริการที่กำหนดจะต้องยาว คุณจะสูญเสียความสามารถที่เป็นนามธรรม

ตัวอย่างเช่นหากคุณจัดการเฉพาะเซสชันเริ่มต้นสิ่งนี้จะดูเหมือนกับ boto3.resource

import boto3 
s3 = boto3.client('s3')

def list_bucket_contents(bucket_name):
   for object in s3.list_objects_v2(Bucket=bucket_name) :
      print(object.key)

list_bucket_contents('Mybucket') 

อย่างไรก็ตามหากคุณต้องการแสดงรายการออบเจ็กต์จากที่ฝากข้อมูลในภูมิภาคต่างๆคุณจะต้องระบุพารามิเตอร์ที่ฝากข้อมูลที่ชัดเจนที่จำเป็นสำหรับลูกค้า

import boto3 
backup_s3 = my_west_session.client('s3',region_name = 'us-west-2')
video_s3 = my_east_session.client('s3',region_name = 'us-east-1')

# you must pass boto3.Session.client and the bucket name 
def list_bucket_contents(s3session, bucket_name):
   response = s3session.list_objects_v2(Bucket=bucket_name)
   if 'Contents' in response:
     for obj in response['Contents']:
        print(obj['key'])

list_bucket_contents(backup_s3, 'backupbucket')
list_bucket_contents(video_s3 , 'videobucket') 

ผู้เยาว์. ไม่ใช่ 'คัดค้าน' คำหลักใช่ไหม
Swagatika

เราควรหลีกเลี่ยงการใช้ทั้ง 'ทรัพยากร' และ 'ไคลเอนต์' ในหนึ่งฟังก์ชันหรือโมดูลแบบขนานหรือไม่?
John Overiron

1
@JohnOveriron บริการ AWS บางบริการนั้นไม่มี "ทรัพยากร" ที่เหมือนกันดังนั้นคุณยังคงต้องการ "ไคลเอ็นต์" ในระดับต่ำ หากคุณตั้งใจจะใช้สำหรับการปรับใช้ขอแนะนำให้ใช้ cloudformation (เป็นการยากที่จะเรียนรู้ แต่จะช่วยคุณประหยัดเวลาในการใช้งานในระยะยาว) กว่าการใช้ API เพื่อทำให้การปรับใช้เป็นไปโดยอัตโนมัติ
mootmoot

@mootmoot แต่การสืบค้น / จัดการบริการ / ทรัพยากร aws สามารถทำได้อย่างง่ายดายโดย APIs เหล่านี้แทนที่จะดึงเอาท์พุทหรืออัปเดตสแต็คผ่านคลาวด์ ฉันถูกไหม?
SK Venkat

@SKVenkat หาก yuu เริ่มสร้างการปรับใช้หลายเซิร์ฟเวอร์โดยใช้ Integration อย่างต่อเนื่อง ฯลฯ การคลาวด์ / terraform / heat นั้นง่ายกว่ามากในการดูแลรักษาจากนั้นใช้รหัส boto3
mootmoot
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.