initial commit
All checks were successful
Build and Upload Python Package / build (push) Successful in 52s

This commit is contained in:
ksyasuda 2024-09-07 19:34:48 -07:00
commit a1fd24c92d
No known key found for this signature in database
10 changed files with 483 additions and 0 deletions

View File

@ -0,0 +1,28 @@
name: Build and Upload Python Package
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine build
- name: Build the package
run: python -m build
- name: Upload to Gitea PyPI Registry
run: |
twine upload --repository-url https://gitea.suda.codes/api/packages/sudacode/pypi -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} dist/*

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.git/*
dist/*
env/*
src/wallabag_api_client.egg-info
src/__pycache__/*
src/wallabag_api_client/__pycache__/*
src/wallabag_api_client/methods/__pycache__/*
tests/test.py

32
pyproject.toml Normal file
View File

@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "wallabag-api-client"
version = "0.0.1"
description = "A Python client to interact with the Wallabag API"
readme = "README.md"
license = { text = "MIT" }
authors = [
{ name = "sudacode", email = "suda@sudacode.com" }
]
dependencies = [
"requests>=2.20.0"
]
requires-python = ">=3.7"
[project.urls]
"Homepage" = "https://gitea.suda.codes/sudacode/wallabag-api-client"
"Source" = "https://gitea.suda.codes/sudacode/wallabag-api-client"
"Issue Tracker" = "https://gitea.suda.codes/sudacode/wallabag-api-client/issues"
[tool.setuptools.packages.find]
where = ["src"]
[project.optional-dependencies]
dev = [
"black",
"pytest",
]

16
requirements.txt Normal file
View File

@ -0,0 +1,16 @@
black==24.8.0
certifi==2024.8.30
charset-normalizer==3.3.2
click==8.1.7
idna==3.8
iniconfig==2.0.0
mypy==1.11.2
mypy-extensions==1.0.0
packaging==24.1
pathspec==0.12.1
platformdirs==4.3.1
pluggy==1.5.0
pytest==8.3.2
requests==2.32.3
typing_extensions==4.12.2
urllib3==2.2.2

View File

@ -0,0 +1,21 @@
from .client import WallabagClient
from .methods.annotations import AnnotationsAPI
from .methods.entries import EntriesAPI
from .methods.tags import TagsAPI
class WallabagAPI:
def __init__(
self,
client_id,
client_secret,
username,
password,
base_url="https://app.wallabag.it",
):
self.client = WallabagClient(
client_id, client_secret, username, password, base_url
)
self.entries = EntriesAPI(self.client)
self.tags = TagsAPI(self.client)
self.annotations = AnnotationsAPI(self.client)

View File

@ -0,0 +1,124 @@
import requests
class WallabagClient:
"""
A client to interact with the Wallabag API using OAuth2 for authentication.
This class handles authentication and sending requests to the API endpoints.
----------
Attributes
client_id : str
The client ID for OAuth2 authentication.
client_secret : str
The client secret for OAuth2 authentication.
username : str
The username of the Wallabag account.
password : str
The password of the Wallabag account.
base_url : str
The base URL of the Wallabag instance.
token : str
The access token obtained from the OAuth2 authentication.
"""
def __init__(
self,
client_id,
client_secret,
username,
password,
base_url="https://app.wallabag.it",
):
"""
Initializes the WallabagClient with user credentials and OAuth2 tokens.
----------
Parameters
client_id : str
The client ID for OAuth2 authentication.
client_secret : str
The client secret for OAuth2 authentication.
username : str
The username of the Wallabag account.
password : str
The password of the Wallabag account.
base_url : str, optional
The base URL of the Wallabag instance (default is "https://app.wallabag.it").
"""
self.client_id = client_id
self.client_secret = client_secret
self.username = username
self.password = password
self.base_url = base_url
self.token = self.authenticate()
def authenticate(self):
"""
Authenticates the user and retrieves the access token using OAuth2.
----------
Returns
str
The access token for making authenticated API requests.
----------
Raises
requests.exceptions.HTTPError
If the authentication request fails.
"""
auth_url = f"{self.base_url}/oauth/v2/token"
data = {
"grant_type": "password",
"client_id": self.client_id,
"client_secret": self.client_secret,
"username": self.username,
"password": self.password,
}
response = requests.post(auth_url, data=data)
response.raise_for_status()
token_info = response.json()
return token_info["access_token"]
def make_request(self, method, endpoint, params=None, data=None):
"""
Makes a request to the Wallabag API with the given parameters.
----------
Parameters
method : str
The HTTP method (GET, POST, DELETE, etc.).
endpoint : str
The API endpoint (e.g., 'entries.json').
params : dict, optional
The query parameters to include in the request.
data : dict, optional
The data to send with the request (for POST, PUT, etc.).
----------
Returns
dict
The response from the API as a dictionary.
----------
Raises
requests.exceptions.HTTPError
If the request fails.
"""
headers = {
"Authorization": f"Bearer {self.token}",
"Content-Type": "application/json",
}
url = f"{self.base_url}/api/{endpoint}"
response = requests.request(
method, url, headers=headers, params=params, json=data
)
response.raise_for_status()
return response.json()

View File

@ -0,0 +1,83 @@
class AnnotationsAPI:
"""
A class to interact with the Wallabag API for managing annotations on entries.
----------
Attributes
client : WallabagClient
The client instance to send API requests.
"""
def __init__(self, client):
"""
Initializes the AnnotationsAPI with the WallabagClient.
----------
Parameters
client : WallabagClient
The WallabagClient instance to send requests.
"""
self.client = client
def get_annotations(self, entry_id):
"""
Retrieves all annotations for a specific entry.
----------
Parameters
entry_id : int
The ID of the entry for which to retrieve annotations.
----------
Returns
dict
The list of annotations for the specified entry.
"""
return self.client.make_request("GET", f"annotations/{entry_id}.json")
def add_annotation(self, entry_id, text, quote):
"""
Adds a new annotation to a specific entry.
----------
Parameters
entry_id : int
The ID of the entry to annotate.
text : str
The text of the annotation.
quote : str
The quote related to the annotation.
----------
Returns
dict
The details of the newly added annotation.
"""
data = {"text": text, "quote": quote}
return self.client.make_request(
"POST", f"annotations/{entry_id}.json", data=data
)
def delete_annotation(self, annotation_id):
"""
Deletes an annotation from a specific entry.
----------
Parameters
annotation_id : int
The ID of the annotation to delete.
----------
Returns
dict
The response from the API after deleting the annotation.
"""
return self.client.make_request("DELETE", f"annotations/{annotation_id}.json")

View File

@ -0,0 +1,98 @@
class EntriesAPI:
"""
A class to interact with the Wallabag API for managing entries (articles).
----------
Attributes
client : WallabagClient
The client instance to send API requests.
"""
def __init__(self, client):
"""
Initializes the EntriesAPI with the WallabagClient.
----------
Parameters
client : WallabagClient
The WallabagClient instance to send requests.
"""
self.client = client
def get_entries(self, page=1, per_page=30):
"""
Retrieves a paginated list of entries (articles).
----------
Parameters
page : int, optional
The page number to retrieve (default is 1).
per_page : int, optional
The number of entries per page (default is 30).
----------
Returns
dict
The list of entries and pagination info.
"""
params = {"page": page, "perPage": per_page}
return self.client.make_request("GET", "entries.json", params=params)
def add_entry(self, url):
"""
Adds a new entry to Wallabag by providing a URL.
----------
Parameters
----------
url : str
The URL of the article to add.
----------
Returns
dict
The details of the newly added entry.
"""
data = {"url": url}
return self.client.make_request("POST", "entries.json", data=data)
def delete_entry(self, entry_id):
"""
Deletes an entry from Wallabag by its entry ID.
----------
Parameters
entry_id : int
The ID of the entry to delete.
----------
Returns
dict
The response from the API after deleting the entry.
"""
return self.client.make_request("DELETE", f"entries/{entry_id}.json")
def get_entry(self, entry_id):
"""
Retrieves the details of a specific entry by its ID.
----------
Parameters
entry_id : int
The ID of the entry to retrieve.
----------
Returns
dict
The details of the specified entry.
"""
return self.client.make_request("GET", f"entries/{entry_id}.json")

View File

@ -0,0 +1,73 @@
class TagsAPI:
"""
A class to interact with the Wallabag API for managing tags.
----------
Attributes
client : WallabagClient
The client instance to send API requests.
"""
def __init__(self, client):
"""
Initializes the TagsAPI with the WallabagClient.
----------
Parameters
client : WallabagClient
The WallabagClient instance to send requests.
"""
self.client = client
def get_tags(self):
"""
Retrieves all tags associated with entries in Wallabag.
----------
Returns
dict
The list of tags.
"""
return self.client.make_request("GET", "tags.json")
def add_tag(self, entry_id, tag):
"""
Adds a tag to a specific entry.
----------
Parameters
entry_id : int
The ID of the entry to tag.
tag : str
The tag to add to the entry.
----------
Returns
dict
The response from the API after adding the tag.
"""
data = {"entry_id": entry_id, "label": tag}
return self.client.make_request("POST", "tags.json", data=data)
def delete_tag(self, tag_id):
"""
Deletes a tag from an entry.
----------
Parameters
tag_id : int
The ID of the tag to delete.
----------
Returns
dict
The response from the API after deleting the tag.
"""
return self.client.make_request("DELETE", f"tags/{tag_id}.json")