Closed thiswillbeyourgithub closed 5 months ago
Currently the feature is not implemented in the python lib. But its a great feature to have. I can see there are already mutations in graphql schema of omnivore, so it should be possible. https://github.com/yazdipour/OmnivoreQL/blob/440101289122d42c4172b165b8667f9fb3ac5c84/omnivoreql/schema.gql#L2527-L2530
Thanks! I'm not familiar with graphQL, so does that mean I can use a request right away? For example gpt4 suggests this. Does that make sense?
import requests
url = 'https://your-graphql-endpoint.com/graphql'
headers = {'Content-Type': 'application/json'}
def create_label(name):
query = '''
mutation {
createLabel(input: {name: "%s"}) {
label {
id
name
}
}
}
''' % name
response = requests.post(url, json={'query': query}, headers=headers)
return response.json()
def update_label(id, new_name):
query = '''
mutation {
updateLabel(input: {id: "%s", name: "%s"}) {
label {
id
name
}
}
}
''' % (id, new_name)
response = requests.post(url, json={'query': query}, headers=headers)
return response.json()
def delete_label(id):
query = '''
mutation {
deleteLabel(id: "%s") {
success
}
}
''' % id
response = requests.post(url, json={'query': query}, headers=headers)
return response.json()
def set_labels(ids):
query = '''
mutation {
setLabels(input: {ids: [%s]}) {
success
}
}
''' % ','.join(f'"{id}"' for id in ids)
response = requests.post(url, json={'query': query}, headers=headers)
return response.json()
well simple answer is to just try it! But my suggestion is to clone this repo, and use https://github.com/yazdipour/OmnivoreQL/blob/main/omnivoreql/omnivoreql.py as example and add you new methods that follows the same sorta structure!
Thank. So I tried and failed.
I notice that your schema seems to be not up to date anymore? https://github.com/omnivore-app/omnivore/blob/main/packages/api/src/schema.ts is linked from https://docs.omnivore.app/integrations/api.html
Anyhow I don't know anything about graphQL, only python so just in case here's what i tried:
I have the following code taken from graphql related files:
input CreateLabelInput { name: String! @sanitize(maxLength: 64) color: String @sanitize(pattern: "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$") description: String @sanitize(maxLength: 100) } input UpdateLabelInput { labelId: ID! color: String! description: String name: String! } input SetLabelsInput { pageId: ID! labelIds: [ID!] labels: [CreateLabelInput!] source: String } createLabel(input: CreateLabelInput!): CreateLabelResult! updateLabel(input: UpdateLabelInput!): UpdateLabelResult! setLabels(input: SetLabelsInput!): SetLabelsResult!
Here are a few reference method:
def save_url(self, url: str): """ Save a URL to Omnivore. :param url: The URL to save. """ mutation = gql( """ mutation { saveUrl(input: { clientRequestId: "%s", source: "api", url: "%s" }) { ... on SaveSuccess { url clientRequestId } ... on SaveError { errorCodes message } } } """ % (uuid.uuid4(), url) ) return self.client.execute(mutation) def save_page(self, url: str, original_content: str): """ Save a page with html content to Omnivore. :param url: The URL of the page to save. :param original_content: The original html content of the page. """ mutation = gql( """ mutation { savePage(input: { clientRequestId: "%s", source: "api", url: "%s", originalContent:"%s" }) { ... on SaveSuccess { url clientRequestId } ... on SaveError { errorCodes message } } } """ % (uuid.uuid4(), url, original_content) ) return self.client.execute(mutation)
I want you to write the methods needed to manage the labels
To which GPT-4o replied:
def create_label(self, name: str, color: str = None, description: str = None):
mutation = gql(
"""
mutation {
createLabel(input: {
name: "%s",
color: "%s",
description: "%s"
}) {
... on CreateLabelResult {
label {
id
name
color
description
}
}
... on CreateLabelError {
errorCodes
message
}
}
}
""" % (name, color, description)
)
return self.client.execute(mutation)
def update_label(self, label_id: str, name: str, color: str = None, description: str = None):
mutation = gql(
"""
mutation {
updateLabel(input: {
labelId: "%s",
name: "%s",
color: "%s",
description: "%s"
}) {
... on UpdateLabelResult {
label {
id
name
color
description
}
}
... on UpdateLabelError {
errorCodes
message
}
}
}
""" % (label_id, name, color, description)
)
return self.client.execute(mutation)
def set_labels(self, page_id: str, label_ids: list, labels: list, source: str = "api"):
label_inputs = ", ".join([
'{ name: "%s", color: "%s", description: "%s" }' % (label['name'], label.get('color', ''), label.get('description', ''))
for label in labels
])
mutation = gql(
"""
mutation {
setLabels(input: {
pageId: "%s",
labelIds: [%s],
labels: [%s],
source: "%s"
}) {
... on SetLabelsResult {
success
}
... on SetLabelsError {
errorCodes
message
}
}
}
""" % (page_id, ', '.join(label_ids), label_inputs, source)
)
return self.client.execute(mutation)
But no matter what I try I seem to get gql.transport.exceptions.TransportQueryError: {'message': 'Unexpected server error'}
which is not at all informative!
Not knowing anything about graphQL and being super short on time, I don't have time to investigate more sadly.
update:
I dug up the android mutation used:
I think a part of my issue is that an argument "pageId" seems to be required even though all my article have "pageId" set to None apparently. Or maybe it's a parsing issue on omnivoreql's side?
Also I can't for the life of me understand what kind of arguments should go as "label_ids" and "label_inputs" even though label_inputs is a list of dict so could completely contain the label ids and not doing so could lead to unexpected errors.
Hey. This weekend i had a bit of time to work on this. And i added some new features like createLabel, updateLabel, deleteLabel
.
But i am still struggling with setLabel
and its WIP.
Regarding pageid: server return clientRequestId as pageid if i am not mistaken.
Thanks a lot!
You are welcome. Btw you can now set your labels while using save_url.
And for the setlabel, pull request is in here but still wip. https://github.com/yazdipour/OmnivoreQL/issues/21
Just to be sure: that means I can currently decide what labels to apply when saving a url, but I can't modify the label of an article I already saved in the past. Correct?
Yes.
@thiswillbeyourgithub set_page_labels, set_page_labels_by_ids
are now added in v0.3.3
Thank you so much! I'll finally be able to move forward my project now!
Hi,
I'm coding something to automatically optimize my reading queue based on ELO scores : https://github.com/thiswillbeyourgithub/mini_LiTOY/blob/main/examples/omnivore_litoy.py
But I'm currently stuck because I don't know how I can use the API to modify labels of an article. I also asked on omnivore repo.
Is that something that could be possible? Or could you tell me how I could use for example a simple python request?
Thanks!