| 
1 | 1 | """Base for interacting with the Censys Search API."""  | 
2 | 2 | import os  | 
3 | 3 | from concurrent.futures import ThreadPoolExecutor, as_completed  | 
4 |  | -from typing import Dict, Iterable, Iterator, List, Optional, Type  | 
 | 4 | +from typing import Any, Dict, Iterable, Iterator, List, Optional, Type  | 
5 | 5 | 
 
  | 
6 | 6 | from requests.models import Response  | 
7 | 7 | 
 
  | 
@@ -74,6 +74,7 @@ def __init__(  | 
74 | 74 |         self.search_path = f"/{self.INDEX_NAME}/search"  | 
75 | 75 |         self.aggregate_path = f"/{self.INDEX_NAME}/aggregate"  | 
76 | 76 |         self.metadata_path = f"/metadata/{self.INDEX_NAME}"  | 
 | 77 | +        self.tags_path = "/tags"  | 
77 | 78 | 
 
  | 
78 | 79 |         # Set up the v1 API  | 
79 | 80 |         v1_kwargs = kwargs.copy()  | 
@@ -286,3 +287,141 @@ def metadata(self) -> dict:  | 
286 | 287 |             dict: The result set returned.  | 
287 | 288 |         """  | 
288 | 289 |         return self._get(self.metadata_path)["result"]  | 
 | 290 | + | 
 | 291 | +    # Comments  | 
 | 292 | + | 
 | 293 | +    def get_comments(self, document_id: str) -> List[dict]:  | 
 | 294 | +        """Get comments for a document.  | 
 | 295 | +
  | 
 | 296 | +        Args:  | 
 | 297 | +            document_id (str): The ID of the document you are requesting.  | 
 | 298 | +
  | 
 | 299 | +        Returns:  | 
 | 300 | +            List[dict]: The list of comments.  | 
 | 301 | +        """  | 
 | 302 | +        return self._get(self.view_path + document_id + "/comments")["result"][  | 
 | 303 | +            "comments"  | 
 | 304 | +        ]  | 
 | 305 | + | 
 | 306 | +    def add_comment(self, document_id: str, contents: str) -> dict:  | 
 | 307 | +        """Add comment to a document.  | 
 | 308 | +
  | 
 | 309 | +        Args:  | 
 | 310 | +            document_id (str): The ID of the document you are requesting.  | 
 | 311 | +            contents (str): The contents of the comment.  | 
 | 312 | +
  | 
 | 313 | +        Returns:  | 
 | 314 | +            dict: The result set returned.  | 
 | 315 | +        """  | 
 | 316 | +        return self._post(  | 
 | 317 | +            self.view_path + document_id + "/comments", data={"contents": contents}  | 
 | 318 | +        )["result"]  | 
 | 319 | + | 
 | 320 | +    # Tags  | 
 | 321 | + | 
 | 322 | +    def list_all_tags(self) -> List[dict]:  | 
 | 323 | +        """List all tags.  | 
 | 324 | +
  | 
 | 325 | +        Returns:  | 
 | 326 | +            List[dict]: The list of tags.  | 
 | 327 | +        """  | 
 | 328 | +        return self._get(self.tags_path)["result"]["tags"]  | 
 | 329 | + | 
 | 330 | +    def create_tag(self, name: str, color: Optional[str] = None) -> dict:  | 
 | 331 | +        """Create a tag.  | 
 | 332 | +
  | 
 | 333 | +        Args:  | 
 | 334 | +            name (str): The name of the tag.  | 
 | 335 | +            color (str): Optional; The color of the tag.  | 
 | 336 | +
  | 
 | 337 | +        Returns:  | 
 | 338 | +            dict: The result set returned.  | 
 | 339 | +        """  | 
 | 340 | +        tag_def: Dict[str, Any] = {"name": name}  | 
 | 341 | +        if color:  | 
 | 342 | +            tag_def["metadata"] = {"color": color}  | 
 | 343 | +        return self._post(self.tags_path, data=tag_def)["result"]  | 
 | 344 | + | 
 | 345 | +    def get_tag(self, tag_id: str) -> dict:  | 
 | 346 | +        """Get a tag.  | 
 | 347 | +
  | 
 | 348 | +        Args:  | 
 | 349 | +            tag_id (str): The ID of the tag.  | 
 | 350 | +
  | 
 | 351 | +        Returns:  | 
 | 352 | +            dict: The result set returned.  | 
 | 353 | +        """  | 
 | 354 | +        return self._get(self.tags_path + "/" + tag_id)["result"]  | 
 | 355 | + | 
 | 356 | +    def update_tag(self, tag_id: str, name: str, color: Optional[str] = None) -> dict:  | 
 | 357 | +        """Update a tag.  | 
 | 358 | +
  | 
 | 359 | +        Args:  | 
 | 360 | +            tag_id (str): The ID of the tag.  | 
 | 361 | +            name (str): The name of the tag.  | 
 | 362 | +            color (str): The color of the tag.  | 
 | 363 | +
  | 
 | 364 | +        Returns:  | 
 | 365 | +            dict: The result set returned.  | 
 | 366 | +        """  | 
 | 367 | +        tag_def: Dict[str, Any] = {"name": name}  | 
 | 368 | +        if color:  | 
 | 369 | +            tag_def["metadata"] = {"color": color}  | 
 | 370 | +        return self._put(  | 
 | 371 | +            self.tags_path + "/" + tag_id,  | 
 | 372 | +            data=tag_def,  | 
 | 373 | +        )["result"]  | 
 | 374 | + | 
 | 375 | +    def delete_tag(self, tag_id: str):  | 
 | 376 | +        """Delete a tag.  | 
 | 377 | +
  | 
 | 378 | +        Args:  | 
 | 379 | +            tag_id (str): The ID of the tag.  | 
 | 380 | +        """  | 
 | 381 | +        self._delete(self.tags_path + "/" + tag_id)  | 
 | 382 | + | 
 | 383 | +    def _list_documents_with_tag(  | 
 | 384 | +        self, tag_id: str, endpoint: str, keyword: str  | 
 | 385 | +    ) -> List[dict]:  | 
 | 386 | +        """List documents by tag.  | 
 | 387 | +
  | 
 | 388 | +        Args:  | 
 | 389 | +            tag_id (str): The ID of the tag.  | 
 | 390 | +            endpoint (str): The endpoint to be called.  | 
 | 391 | +            keyword (str): The keyword to be used in the endpoint.  | 
 | 392 | +
  | 
 | 393 | +        Returns:  | 
 | 394 | +            List[dict]: The list of documents.  | 
 | 395 | +        """  | 
 | 396 | +        return self._get(self.tags_path + "/" + tag_id + "/" + endpoint)["result"][  | 
 | 397 | +            keyword  | 
 | 398 | +        ]  | 
 | 399 | + | 
 | 400 | +    def list_tags_on_document(self, document_id: str) -> List[dict]:  | 
 | 401 | +        """List tags on a document.  | 
 | 402 | +
  | 
 | 403 | +        Args:  | 
 | 404 | +            document_id (str): The ID of the document.  | 
 | 405 | +
  | 
 | 406 | +        Returns:  | 
 | 407 | +            List[dict]: The list of tags.  | 
 | 408 | +        """  | 
 | 409 | +        return self._get(self.view_path + document_id + "/tags")["result"]["tags"]  | 
 | 410 | + | 
 | 411 | +    def add_tag_to_document(self, document_id: str, tag_id: str):  | 
 | 412 | +        """Add a tag to a document.  | 
 | 413 | +
  | 
 | 414 | +        Args:  | 
 | 415 | +            document_id (str): The ID of the document.  | 
 | 416 | +            tag_id (str): The ID of the tag.  | 
 | 417 | +        """  | 
 | 418 | +        self._put(self.view_path + document_id + "/tags/" + tag_id)  | 
 | 419 | + | 
 | 420 | +    def remove_tag_from_document(self, document_id: str, tag_id: str):  | 
 | 421 | +        """Remove a tag from a document.  | 
 | 422 | +
  | 
 | 423 | +        Args:  | 
 | 424 | +            document_id (str): The ID of the document.  | 
 | 425 | +            tag_id (str): The ID of the tag.  | 
 | 426 | +        """  | 
 | 427 | +        self._delete(self.view_path + document_id + "/tags/" + tag_id)  | 
0 commit comments