-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update post not working with new piazza api #69
Comments
just ran into this issue. seems like the current code for updating posts is outdated. for reference, here's an example payload submitted in the browser (found via network inspector tool in firefox): {
"method": "content.update",
"params": {
"cid": "m2jjb4r7c2i2t2",
"type": "question",
"subject": "Analysis, Fall 2022 #3",
"content": "<md>babaenenen</md>",
"anonymous": "no",
"editor": "md",
"revision": 2,
"must_read": false,
"config": {},
"folders": [
"analysis"
],
"visibility": "all"
}
} meanwhile, here's the current piazza-api/piazza_api/network.py Lines 259 to 282 in acb5de9
for starters, it's not the case (at least, not anymore) that the content should be submitted in the i haven't tried fixing it but it might be the case that we also need to submit a |
Thanks @kwshi for the tip! Below is a relatively complete working example that ended up working as a hot fix. I'm happy to make this an MR since it's a very small code change. from pydantic import BaseModel, Field
from piazza_api import Piazza
from typing import Literal, List
import types
class UpdatePostModel(BaseModel):
cid: int
post_type: Literal["note", "question"] = Field(default="note")
post_folders: List[str] | None = Field(default=None)
post_subject: str | None = Field(default=None)
post_content: str
visible_to: str | None = Field(default=None)
is_announcement: int = 0
bypass_email: int = 1
anonymous: bool = False
def update_post(
self,
cid: int,
post_type: str,
post_folders: str,
post_subject: str,
post_content: str,
history_size: int,
is_announcement: int = 0,
bypass_email: int = 1,
anonymous: bool = False,
): # pragma: no cover
"""Update a post, the **updated** way!
It seems like if the post has `<p>` tags, then it's treated as HTML,
but is treated as text otherwise. You'll want to provide `content`
accordingly.
:type post_type: str
:param post_type: 'note', 'question'
:type post_folders: str
:param post_folders: Folder to put post into
:type post_subject: str
:param post_subject: Subject string
:type post_content: str
:param post_content: Content string
:type visible_to: str
:param visible_to: Users this post is visible to
:type is_announcement: bool
:param is_announcement:
:type bypass_email: bool
:param bypass_email:
:type anonymous: bool
:param anonymous:
:rtype: dict
:returns: Dictionary with information about the created post.
"""
params = {
"cid": cid,
"anonymous": "yes" if anonymous else "no",
"subject": post_subject,
"content": post_content,
"folders": post_folders,
"type": post_type,
"revision": history_size + 1, # autoincrement based on a post's history_size on return
"config": {
"bypass_email": bypass_email,
"is_announcement": is_announcement,
},
}
return self._rpc.content_update(params)
piazza_access = Piazza()
# this is where you plug in your email and password (had to ask Piazza engineers to
# whitelist our email depending on the college/course setup)
piazza_access.user_login(
email=login_credentials.email,
password=login_credentials.password.get_secret_value(),
)
# login to that specific course.
course_logged = piazza_access.network(network_id=login_credentials.course_id)
# add the monkeypatch from definition above
course.update_post = types.MethodType(update_post_monkeypatch, course)
lecture_content_to_look_for = "Post to Update"
# Assuming you're looking for a post with a specific string in the title/body.
for post in course.iter_all_posts(
limit=10, sleep=5
):
if lecture_content_to_look_for in post["history"][0]["content"]:
# grab the post cid, subject header, folder and other details
lecture_cid = post["id"]
lecture_subject = post["history"][0]["subject"]
lecture_folder = post["folders"]
lecture_type = post["type"]
history_size = post["history_size"] # this is super important to get the `revision` to work.
# Actually update the post with whatever html content you want.
returned_content = course.update_post(
**UpdatePostModel(
cid=post_id,
post_type="note",
post_folders=["other"],
visible_to=posted_to,
post_content="<some updated post content here!>",
post_subject=lecture_subject + f": rev {history_size}",
).model_dump()
)
print(returned_content) # if no errors, you'll see the post with updated content returned here. |
So far I've been able to get posts to create, but not update. Since a semi-recent update to their backend, I've had to monkeypatch the
create_post
piazza api seen below for working example:However, no luck for updating posts, anything similar like feeding in cid (post id) and post content, and any permutation of the additional info needed for the create monkeypatch, gives the same response:
Something to do with this url made to piazza's backend:
https://piazza.com/logic/api?method=content.update&aid=<aid-nonce_here>
Response: {\n "result": null,\n "error_codes": [],\n "error": "The post you are looking for cannot be found",\n "aid": "luxl22pj6p74en"\n}
I've tried every permutation or including or excluding things, and haven't been able to make any headway, so I'm a bit stumped! Any ideas? Happy to do some work on this if someone knows a fix.
The text was updated successfully, but these errors were encountered: