Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Documentation
organizations
changelog
credits
projects


Contributing
Expand Down
95 changes: 95 additions & 0 deletions docs/projects.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
Projects
===========

Methods for searching and retrieving projects.

ProjectClient
----------------
.. class:: documentcloud.projects.ProjectClient

The project client allows access to search, list, and retrieve projects. Accessed generally as ``client.projects``.
::

.. method:: list(self, **params)

List all projects with optional filtering. Available filters include:

- **contributors**: Filter by the unique identifier of a user associated with the project.
- **requests**: Filter by projects which have this request associated with it.
- **title**: Filter by the title of the project. Supports partial matches. Case sensitive.

:param params: Query parameters to filter results, such as `contributors`, `requests`, and `title`.
:return: An :class:`APIResults` object containing the list of projects.

.. method:: retrieve(self, project_id)

Retrieve a specific project by its ID

:param project_id: The unique ID of the project to retrieve.
:return: A :class:`Project` object representing the requested project.

Project
----------------
.. class:: documentcloud.projects.Project

A representation of a single project.

.. method:: str()

Return a string representation of the project in format: `Project {id} - Title: {title}`.

.. attribute:: id

The unique numerical identifier for the project.

.. attribute:: title

The title of the project.

.. attribute:: slug

A short, URL-friendly version of the project's title.

.. attribute:: summary

A brief summary of the project.

.. attribute:: description

A detailed description of the project.

.. attribute:: image

The image associated with the project (if available).

.. attribute:: private

A boolean indicating whether the project is private (`true`) or public (`false`).

.. attribute:: approved

A boolean indicating whether the project has been approved (`true`) or not (`false`).

.. attribute:: featured

A boolean indicating whether the project is featured on the MuckRock site (`true`) or not (`false`).

.. attribute:: contributors

A list of user IDs representing the contributors to the project.

.. attribute:: articles

A list of article IDs associated with the project.

.. attribute:: requests

A list of request IDs associated with the project.

.. attribute:: date_created

The date and time when the project was created. If null, the creation date is not set.

.. attribute:: date_approved

The date and time when the project was approved. If null, the approval date is not set.
2 changes: 1 addition & 1 deletion docs/users.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ UserClient
----------------
.. class:: documentcloud.users.UserClient

The user client allows access to search, list, and retrieve individual users. Accessed generally as ``client.organizations``.
The user client allows access to search, list, and retrieve individual users. Accessed generally as ``client.users``.
::
>>> my_user = client.users.me()

Expand Down
2 changes: 2 additions & 0 deletions src/muckrock/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .files import FileClient
from .jurisdictions import JurisdictionClient
from .organizations import OrganizationClient
from .projects import ProjectClient
# Local Imports
from .requests import RequestClient
from .users import UserClient
Expand Down Expand Up @@ -62,3 +63,4 @@ def __init__(
self.files = FileClient(self)
self.organizations = OrganizationClient(self)
self.users = UserClient(self)
self.projects = ProjectClient(self)
47 changes: 47 additions & 0 deletions src/muckrock/projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""
Projects
"""

# Standard Library
import logging

# Local
from .base import APIResults, BaseAPIClient, BaseAPIObject

logger = logging.getLogger("projects")


class Project(BaseAPIObject):
"""A single user object."""

api_path = "projects"

def __str__(self):
return f"Project {self.id} - Title: {self.title}" # pylint:disable=no-member


class ProjectClient(BaseAPIClient):
"""Client for interacting with users."""

api_path = "projects"
resource = Project

def retrieve(self, project_id):
"""
Retrieve a single project by its ID.

:param project_id: The ID of the project to retrieve.
:return: A project object.
"""
response = self.client.get(f"{self.api_path}/{project_id}/")
return Project(self.client, response.json())

def list(self, **params):
"""
List all projects with optional filtering.

:param params: Query parameters to filter results
:return: APIResults containing User objects.
"""
response = self.client.get(self.api_path, params=params)
return APIResults(self.resource, self.client, response)
13 changes: 13 additions & 0 deletions src/muckrock/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,16 @@ def test_retrieve_users_nonstaff(regular_user_client):
user_id = 1
with pytest.raises(DoesNotExistError):
regular_user_client.users.retrieve(user_id)


def test_list_projects(muckrock_client):
projects = muckrock_client.projects.list()
assert projects, "Expected a non-empty list of communications."
print(projects)


def test_retrieve_projects(muckrock_client):
project_id = 10
project = muckrock_client.projects.retrieve(project_id)
assert project.id == project_id, f"Expected request ID to be {project_id}."
print(project)