【发布时间】:2022-01-22 11:22:44
【问题描述】:
目标
当学生完成作业或为任何课程添加作业时,触发更新 Cloud Firestore 的功能。
问题
official docs 声明 CourseWorkChangesInfo 的提要需要 courseId,我希望避免为每个课程注册和订阅,每个课程都在自己的线程上运行。
我有什么
我已经成功注册了一门课程:
def registration_body():
return { # An instruction to Classroom to send notifications from the `feed` to the
# provided destination.
"feed": { # Information about a `Feed` with a `feed_type` of `COURSE_WORK_CHANGES`.
"feedType": "COURSE_WORK_CHANGES", # Information about a `Feed` with a `feed_type` of `COURSE_WORK_CHANGES`.
"courseWorkChangesInfo": {
# This field must be specified if `feed_type` is `COURSE_WORK_CHANGES`.
"courseId": "xxxxxxxxxxxx", # The `course_id` of the course to subscribe to work changes for.
},
},
"cloudPubsubTopic": {
"topicName": "projects/xxxxx/topics/gcr-course", # The `name` field of a Cloud Pub/Sub
},
}
def create_registration(service):
"""
Creates a registration to the Google Classroom Service which will listen
for updates on Google Classroom according to the requested body.
Pub Sub will emit a payload to subscribers when a classroom upate occurs.
Args:
service (Google Classroom Service): Google Classroom Service as retrieved
from the Google Aclassroom Service builder
Returns:
Registration: Google Classroom Registration
"""
body = registration_body()
try:
registration = service.registrations().create(body=body).execute()
print(f"Registration to Google CLassroom Created\n{registration}")
return registration
except Exception as e:
print(e)
raise
并且我能够在我的 FastAPI 服务器旁边成功订阅这些更新:
def init_subscription():
# [INIT PUBSUB SUBSCRIBER AND CALLBACKS]
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(
"x-student-portal", "gcr-course-sub"
)
future = subscriber.subscribe(subscription_path, callback)
with subscriber:
try:
future.result()
except TimeoutError:
future.cancel()
future.result()
def callback(message):
print("message recieved")
# do_stuff(message)
print(message)
message.ack()
注册和订阅初始化:
@app.on_event("startup")
async def startup_event():
global db
global gc_api
global gc_service
global gc_registration
global future
global pub_sub_subscription_thread
db = firestore.FirestoreDatabase()
gc_service = get_service()
gc_api = ClassroomApi(service=gc_service)
gc_registration = publisher_client.create_registration(gc_service)
pub_sub_subscription_thread = multiprocessing.Process(
target=publisher_client.init_subscription
)
pub_sub_subscription_thread.start()
结论
我非常希望避免运行多个线程,同时仍然能够订阅我所有课程中的更改。
任何建议将不胜感激。
【问题讨论】:
标签: python google-api google-cloud-pubsub fastapi google-classroom