hubcap


Namehubcap JSON
Version 0.1.7 PyPI version JSON
download
home_pagehttps://github.com/thorwhalen/hubcap
SummaryA py2store (i.e. dict-like) interface to github
upload_time2024-11-15 13:34:28
maintainerNone
docs_urlNone
authorThor Whalen
requires_pythonNone
licenseapache-2.0
keywords github
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # hubcap
A [dol](https://github.com/i2mint/dol) (i.e. dict-like) interface to github

To install:	```pip install hubcap```


# Examples

## Basics

The simplest facade to github data.

Interact with github like you'd interact with a `dict` object.

Warning: You'll need to have a github api token (google it if you don't have one;
it's easy to get). You'll have to specify this token when making hubcap objects,
or put it in an environmental variable under the name `GITHUB_TOKEN` or `HUBCAP_GITHUB_TOKEN` 
(useful since github actions doesn't allow you to have env variables starting with `GITHUB`).


```python
>>> s = GitHubReader('thorwhalen')  # connnecting to a particular user/organization
>>> list(s)  # doctest: +SKIP
['agen',
 'aix',
 ...
 'viral',
 'wealth',
 'wrapt']
>>> 'a_non_existing_repository_name' in s
False
>>> 'hubcap' in s  # of course, this will be true, it's what you're using now!
True
>>> repo = s['hubcap']
>>> list(repo)
['master']
>>> branch = repo['master']
>>> list(branch)  # doctest: +NORMALIZE_WHITESPACE
['/.gitattributes',
 '/.github/',
 '/.gitignore',
 '/LICENSE',
 '/README.md',
 '/docsrc/',
 '/hubcap/',
 '/setup.cfg',
 '/setup.py']
>>> content = branch['/setup.cfg']
>>> print(content[:32].decode())
[metadata]
name = hubcap
version
```


## Listing repositories and information about them


List repositories for a given user or organization, along with 78 fields of info.

```python
>>> from hubcap.examples import repos_info, actions_info
>>>
>>> repos = repos_info('i2mint')  # doctest: +SKIP
>>> print(repos.shape)   # doctest: +SKIP
(60, 78)
>>> repos.head()  # doctest: +SKIP
                         id                           node_id       name  ... watchers  default_branch                                        permissions
full_name                                                                 ...
i2mint/py2mqtt    425694616                      R_kgDOGV-VmA    py2mqtt  ...        0            main  {'admin': True, 'maintain': True, 'push': True...
i2mint/mongodol   341721959  MDEwOlJlcG9zaXRvcnkzNDE3MjE5NTk=   mongodol  ...        0          master  {'admin': True, 'maintain': True, 'push': True...
i2mint/dol        299438731  MDEwOlJlcG9zaXRvcnkyOTk0Mzg3MzE=        dol  ...        4          master  {'admin': True, 'maintain': True, 'push': True...
i2mint/stream2py  238989487  MDEwOlJlcG9zaXRvcnkyMzg5ODk0ODc=  stream2py  ...        2          master  {'admin': True, 'maintain': True, 'push': True...
i2mint/creek      321448350  MDEwOlJlcG9zaXRvcnkzMjE0NDgzNTA=      creek  ...        0          master  {'admin': True, 'maintain': True, 'push': True...

[5 rows x 78 columns]
>>> list(repos.columns)   # doctest: +SKIP
['id', 'node_id', 'name', 'full_name', 'private', 'owner', 'html_url', 'description',
'fork', 'url', 'forks_url', 'keys_url', 'collaborators_url', 'teams_url', 'hooks_url
', 'issue_events_url', 'events_url', 'assignees_url', 'branches_url', 'tags_url',
'blobs_url', 'git_tags_url', 'git_refs_url', 'trees_url', 'statuses_url', 'languages_url
', 'stargazers_url', 'contributors_url', 'subscribers_url', 'subscription_url',
'commits_url', 'git_commits_url', 'comments_url', 'issue_comment_url', 'contents_url',
'compare_url', 'merges_url', 'archive_url', 'downloads_url', 'issues_url', 'pulls_url',
'milestones_url', 'notifications_url', 'labels_url', 'releases_url', 'deployments_url
', 'created_at', 'updated_at', 'pushed_at', 'git_url', 'ssh_url', 'clone_url', 'svn_url',
'homepage', 'size', 'stargazers_count', 'watchers_count', 'language', 'has_issue
s', 'has_projects', 'has_downloads', 'has_wiki', 'has_pages', 'forks_count',
'mirror_url', 'archived', 'disabled', 'open_issues_count', 'license', 'allow_forking',
'is_template', 'topics', 'visibility', 'forks', 'open_issues', 'watchers',
'default_branch', 'permissions']

```


Get info about github actions for a given repository.

```python
>>> actions = actions_info('i2mint/mongodol')   # doctest: +SKIP
>>> print(actions.shape)   # doctest: +SKIP
(10, 30)
>>> actions.head()    # doctest: +SKIP
           id                    name  ...                                         repository                                    head_repository
0  1468986198  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...
1  1445456774  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...
2  1437461380  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...
3  1343133456  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...
4  1262878182  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...

[5 rows x 30 columns]
>>>
>>> list(actions.columns)   # doctest: +SKIP
['id', 'name', 'node_id', 'head_branch', 'head_sha', 'run_number', 'event', 'status',
'conclusion', 'workflow_id', 'check_suite_id', 'check_suite_node_id', 'url', 'html_url',
'pull_requests', 'created_at', 'updated_at', 'run_attempt', 'run_started_at',
'jobs_url', 'logs_url', 'check_suite_url', 'artifacts_url', 'cancel_url', 'rerun_url',
'previous_attempt_url', 'workflow_url', 'head_commit', 'repository', 'head_repository']
```


Find most recently changed repositories and check if their CI failed or not.

```python
>>> from hubcap.examples import date_selection_lidx
>>> updated_recently = repos.iloc
...     [date_selection_lidx(repos, hours_ago=24)]  # doctest: +SKIP
>>> {repo: get_last_build_status(repo)
...     for repo in updated_recently['full_name']}  # doctest: +SKIP
{'i2mint/py2mqtt': 'failure',
 'i2mint/mongodol': 'success',
 'i2mint/dol': 'success',
 'i2mint/stream2py': 'success',
 'i2mint/creek': 'success'}
```


Note: You can get this directly using the `ci_status` function

```python
>>> from hubcap.examples import ci_status
>>> ci_status('i2mint', hours_ago=24)  # doctest: +SKIP
{'i2mint/py2mqtt': 'failure',
 'i2mint/mongodol': 'success',
 'i2mint/dol': 'success',
 'i2mint/stream2py': 'success',
 'i2mint/creek': 'success'}
```


## RepoReader

```python
>>> from hubcap import RepoReader
>>> r = RepoReader('thorwhalen/test_repo')
>>> sorted(r)  # doctest: +SKIP
['artifacts', 'assignees', 'autolinks', 'branches', 'codescan_alerts', 'collaborators', 
'comments', 'commits', 'contributors', 'deployments', 'discussions', 'downloads', 
'environments', 'events', 'forks', 'git_refs', 'hooks', 'issues', 'issues_comments', 
'issues_events', 'labels', 'languages', 'milestones', 'network_events', 
'notifications', 'pending_invitations', 'projects', 'pulls', 'pulls_comments', 
'pulls_review_comments', 'releases', 'repository_advisories', 'secrets', 
'self_hosted_runners', 'stargazers', 'stargazers_with_dates', 'stats_contributors', 
'subscribers', 'tags', 'teams', 'top_paths', 'top_referrers', 'topics', 'variables', 
'watchers', 'workflow_runs', 'workflows']
>>>
>>> 'issues' in r
True
>>> issues = r['issues']
>>> sorted(issues)
[4, 5]
>>> issue_obj = issues[4]
>>> issue_obj
Issue(title="Test Issue A", number=4)
>>> sorted([attr for attr in dir(issue_obj) if not attr.startswith('_')])  # doctest: +SKIP
['CHECK_AFTER_INIT_FLAG', 'active_lock_reason', 'add_to_assignees', 'add_to_labels', 
'as_pull_request', 'assignee', 'assignees', 'body', 'closed_at', 'closed_by', 
'comments', 'comments_url', 'create_comment', 'create_reaction', 'created_at', 
'delete_labels', 'delete_reaction', 'edit', 'etag', 'events_url', 'get__repr__', 
'get_comment', 'get_comments', 'get_events', 'get_labels', 'get_reactions', 
'get_timeline', 'html_url', 'id', 'labels', 'labels_url', 'last_modified', 'lock', 
'locked', 'milestone', 'number', 'pull_request', 'raw_data', 'raw_headers', 
'remove_from_assignees', 'remove_from_labels', 'repository', 'setCheckAfterInitFlag', 
'set_labels', 'state', 'state_reason', 'title', 'unlock', 'update', 'updated_at', 
'url', 'user']
>>> issue_obj.number
4
>>> issue_obj.state
'open'
>>> issue_obj.labels
[Label(name="documentation"), Label(name="enhancement")]
>>> # title of issue
>>> issue_obj.title
'Test Issue A'
>>> # content of issue
>>> issue_obj.body
'Contents of Test Issue A'
>>>
>>> issue_obj.comments
2
>>>
>>> list(issue_obj.get_comments())  # doctest: +NORMALIZE_WHITESPACE
[IssueComment(user=NamedUser(login="thorwhalen"), id=1801792378), 
IssueComment(user=NamedUser(login="thorwhalen"), id=1801792855)]
>>> issue_comment = issue_obj.get_comment(1801792378)
>>> issue_comment.body
'Comment 1 of Test Issue A'
>>>
>>> 'discussions' in r
True
>>> discussions = r['discussions']  # doctest: +SKIP
>>> sorted(discussions)  # doctest: +SKIP
[1, 2, 3]
```


## hub function

The high level function `hub` is the simplest way to get started. It's a
function that takes a path to a github resource and returns a mapping to that
resource. The mapping is lazy, so it's only when you access a key that the
resource is actually fetched from github.

```python
>>> repositories = hub('thorwhalen')
>>> 'hubcap' in repositories
True
>>> hubcap_repo = repositories['hubcap']
>>>
>>> repo = hub('thorwhalen/hubcap')
>>> 'master' in repo
True
>>> master_files = repo['master']
>>>
>>> files = hub('thorwhalen/hubcap/master')
>>> '/README.md' in files
True
>>> '/hubcap/' in files
True
>>> hubcap_files = files['/hubcap/']
>>> '/hubcap/base.py' in hubcap_files
True
```

### Access issues

```python
>>> issues = hub('thorwhalen/hubcap/issues')
>>> 3 in issues  # there's a "number 3" issue
True
>>> issue = issues[3]
>>> issue.title
'Test Issue'
>>> issue.body
'This is just a test issue to test that hubcap can see it.\r\n'
>>> issue.comments  # meaning "number of comments"
1
```

### Access discussions

```python
>>> discussions = hub('thorwhalen/hubcap/discussions')  # doctest: +SKIP
>>> # get a list of discussion (keys)
>>> list(discussions)  # doctest: +SKIP
[2, ...]
>>> # the discussion 2 should be included in that list
>>> 2 in discussions  # doctest: +SKIP
True
>>> discussion = discussions[2]   # doctest: +SKIP
>>> discussion  # doctest: +SKIP
{'number': 2,
 'title': 'Root interface of hubcap',
 'body': 'Every time I need to do something with `hubcap` ...',
 'author': {'login': 'thorwhalen'},
 'createdAt': '2023-11-07T09:30:59Z',
 'updatedAt': '2023-12-05T08:25:39Z',
 'comments': [{'body': 'Further it would be nice if we ...',
   'author': 'thorwhalen',
   'replies': []}]}
>>> discussion['title']    # doctest: +SKIP
'Root interface of hubcap'
```

Here's a nice trick for those want to download a discussion in a nice readable format, 
for you, or some AI, to look through. 

```python 
>>> from hubcap import create_markdown_from_jdict
>>> markdown_string = create_markdown_from_jdict(discussion)  # doctest: +SKIP
>>> print(markdown_string)  # doctest: +SKIP
# Root interface of hubcap
<BLANKLINE>
Every time I need to do something with `hubcap` I need to look up how it works again. 
<BLANKLINE>
That's negative points
```

## GithubReader

One of the main classes is `GithubReader`. It's a mapping that connects to a
github user or organization, and returns a mapping of repositories. The
repositories are also mappings, that return mappings of branches, and so on.

```python
>>> from hubcap import GithubReader
>>> s = GithubReader('thorwhalen')  # connnecting to a particular user/organization
>>> list(s)  # doctest: +SKIP
['agen',
 'aix',
 ...
 'viral',
 'wealth',
 'wrapt']
>>> 'a_non_existing_repository_name' in s
False
>>> 'hubcap' in s  # of course, this will be true, it's what you're using now!
True
>>> repo = s['hubcap']
>>> list(repo)
['master']
>>> branch = repo['master']
>>> list(branch)  # doctest: +NORMALIZE_WHITESPACE
['/.gitattributes', '/.github/', '/.gitignore', '/LICENSE',
'/README.md', '/docsrc/', '/hubcap/', '/misc/', '/setup.cfg', '/setup.py']
>>> content = branch['/setup.cfg']
>>> print(content[:32].decode())
[metadata]
name = hubcap
version

>>> from hubcap import get_repository_info
>>> info = get_repository_info('thorwhalen/hubcap')
>>> list(info)  # doctest: +NORMALIZE_WHITESPACE
['name', 'full_name', 'description', 'stargazers_count',
'forks_count', 'watchers_count', 'html_url', 'last_commit_date']
>>> info['name']
'hubcap'
>>> info['html_url']
'https://github.com/thorwhalen/hubcap'
>>> info['stargazers_count'] >= 1
True
```

You also have other useful objects, like `Issues`, `IssueComments`, `Discussions`, etc.   


## github_repo_text_aggregate

```python
>>> owner_repo_files = github_repo_text_aggregate('thorwhalen/hubcap')  # doctest: +SKIP
>>> markdown_output = github_repo_text_aggregate(owner_repo_files)  # doctest: +SKIP
```


# Recipes

## Clone to temp folder and get store (mapping) of files

```python
from hubcap import git_clone, git_wiki_clone
from dol import TextFiles, filt_iter, Pipe

repo_py_files = Pipe(
    git_clone, TextFiles, filt_iter(filt=lambda x: x.endswith('.py'))
)
repo_wiki_files = Pipe(git_wiki_clone, TextFiles)
```

```python
py_files = repo_py_files('i2mint/dol')
len(py_files)
# 37
```

```python
wiki_files = repo_wiki_files('i2mint/dol')
list(wiki_files)
# ['Recipes.md',
#  'Critiques-and-their-comebacks.md',
#  'Home.md',
#  'Mapping-Views.md']
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/thorwhalen/hubcap",
    "name": "hubcap",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "github",
    "author": "Thor Whalen",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/a1/69/0fc2bc6d36ec3a4e3c267a7255e26fda8b0502492b850043b1c919aaab53/hubcap-0.1.7.tar.gz",
    "platform": "any",
    "description": "# hubcap\nA [dol](https://github.com/i2mint/dol) (i.e. dict-like) interface to github\n\nTo install:\t```pip install hubcap```\n\n\n# Examples\n\n## Basics\n\nThe simplest facade to github data.\n\nInteract with github like you'd interact with a `dict` object.\n\nWarning: You'll need to have a github api token (google it if you don't have one;\nit's easy to get). You'll have to specify this token when making hubcap objects,\nor put it in an environmental variable under the name `GITHUB_TOKEN` or `HUBCAP_GITHUB_TOKEN` \n(useful since github actions doesn't allow you to have env variables starting with `GITHUB`).\n\n\n```python\n>>> s = GitHubReader('thorwhalen')  # connnecting to a particular user/organization\n>>> list(s)  # doctest: +SKIP\n['agen',\n 'aix',\n ...\n 'viral',\n 'wealth',\n 'wrapt']\n>>> 'a_non_existing_repository_name' in s\nFalse\n>>> 'hubcap' in s  # of course, this will be true, it's what you're using now!\nTrue\n>>> repo = s['hubcap']\n>>> list(repo)\n['master']\n>>> branch = repo['master']\n>>> list(branch)  # doctest: +NORMALIZE_WHITESPACE\n['/.gitattributes',\n '/.github/',\n '/.gitignore',\n '/LICENSE',\n '/README.md',\n '/docsrc/',\n '/hubcap/',\n '/setup.cfg',\n '/setup.py']\n>>> content = branch['/setup.cfg']\n>>> print(content[:32].decode())\n[metadata]\nname = hubcap\nversion\n```\n\n\n## Listing repositories and information about them\n\n\nList repositories for a given user or organization, along with 78 fields of info.\n\n```python\n>>> from hubcap.examples import repos_info, actions_info\n>>>\n>>> repos = repos_info('i2mint')  # doctest: +SKIP\n>>> print(repos.shape)   # doctest: +SKIP\n(60, 78)\n>>> repos.head()  # doctest: +SKIP\n                         id                           node_id       name  ... watchers  default_branch                                        permissions\nfull_name                                                                 ...\ni2mint/py2mqtt    425694616                      R_kgDOGV-VmA    py2mqtt  ...        0            main  {'admin': True, 'maintain': True, 'push': True...\ni2mint/mongodol   341721959  MDEwOlJlcG9zaXRvcnkzNDE3MjE5NTk=   mongodol  ...        0          master  {'admin': True, 'maintain': True, 'push': True...\ni2mint/dol        299438731  MDEwOlJlcG9zaXRvcnkyOTk0Mzg3MzE=        dol  ...        4          master  {'admin': True, 'maintain': True, 'push': True...\ni2mint/stream2py  238989487  MDEwOlJlcG9zaXRvcnkyMzg5ODk0ODc=  stream2py  ...        2          master  {'admin': True, 'maintain': True, 'push': True...\ni2mint/creek      321448350  MDEwOlJlcG9zaXRvcnkzMjE0NDgzNTA=      creek  ...        0          master  {'admin': True, 'maintain': True, 'push': True...\n\n[5 rows x 78 columns]\n>>> list(repos.columns)   # doctest: +SKIP\n['id', 'node_id', 'name', 'full_name', 'private', 'owner', 'html_url', 'description',\n'fork', 'url', 'forks_url', 'keys_url', 'collaborators_url', 'teams_url', 'hooks_url\n', 'issue_events_url', 'events_url', 'assignees_url', 'branches_url', 'tags_url',\n'blobs_url', 'git_tags_url', 'git_refs_url', 'trees_url', 'statuses_url', 'languages_url\n', 'stargazers_url', 'contributors_url', 'subscribers_url', 'subscription_url',\n'commits_url', 'git_commits_url', 'comments_url', 'issue_comment_url', 'contents_url',\n'compare_url', 'merges_url', 'archive_url', 'downloads_url', 'issues_url', 'pulls_url',\n'milestones_url', 'notifications_url', 'labels_url', 'releases_url', 'deployments_url\n', 'created_at', 'updated_at', 'pushed_at', 'git_url', 'ssh_url', 'clone_url', 'svn_url',\n'homepage', 'size', 'stargazers_count', 'watchers_count', 'language', 'has_issue\ns', 'has_projects', 'has_downloads', 'has_wiki', 'has_pages', 'forks_count',\n'mirror_url', 'archived', 'disabled', 'open_issues_count', 'license', 'allow_forking',\n'is_template', 'topics', 'visibility', 'forks', 'open_issues', 'watchers',\n'default_branch', 'permissions']\n\n```\n\n\nGet info about github actions for a given repository.\n\n```python\n>>> actions = actions_info('i2mint/mongodol')   # doctest: +SKIP\n>>> print(actions.shape)   # doctest: +SKIP\n(10, 30)\n>>> actions.head()    # doctest: +SKIP\n           id                    name  ...                                         repository                                    head_repository\n0  1468986198  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...\n1  1445456774  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...\n2  1437461380  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...\n3  1343133456  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...\n4  1262878182  Continuous Integration  ...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...  {'id': 341721959, 'node_id': 'MDEwOlJlcG9zaXRv...\n\n[5 rows x 30 columns]\n>>>\n>>> list(actions.columns)   # doctest: +SKIP\n['id', 'name', 'node_id', 'head_branch', 'head_sha', 'run_number', 'event', 'status',\n'conclusion', 'workflow_id', 'check_suite_id', 'check_suite_node_id', 'url', 'html_url',\n'pull_requests', 'created_at', 'updated_at', 'run_attempt', 'run_started_at',\n'jobs_url', 'logs_url', 'check_suite_url', 'artifacts_url', 'cancel_url', 'rerun_url',\n'previous_attempt_url', 'workflow_url', 'head_commit', 'repository', 'head_repository']\n```\n\n\nFind most recently changed repositories and check if their CI failed or not.\n\n```python\n>>> from hubcap.examples import date_selection_lidx\n>>> updated_recently = repos.iloc\n...     [date_selection_lidx(repos, hours_ago=24)]  # doctest: +SKIP\n>>> {repo: get_last_build_status(repo)\n...     for repo in updated_recently['full_name']}  # doctest: +SKIP\n{'i2mint/py2mqtt': 'failure',\n 'i2mint/mongodol': 'success',\n 'i2mint/dol': 'success',\n 'i2mint/stream2py': 'success',\n 'i2mint/creek': 'success'}\n```\n\n\nNote: You can get this directly using the `ci_status` function\n\n```python\n>>> from hubcap.examples import ci_status\n>>> ci_status('i2mint', hours_ago=24)  # doctest: +SKIP\n{'i2mint/py2mqtt': 'failure',\n 'i2mint/mongodol': 'success',\n 'i2mint/dol': 'success',\n 'i2mint/stream2py': 'success',\n 'i2mint/creek': 'success'}\n```\n\n\n## RepoReader\n\n```python\n>>> from hubcap import RepoReader\n>>> r = RepoReader('thorwhalen/test_repo')\n>>> sorted(r)  # doctest: +SKIP\n['artifacts', 'assignees', 'autolinks', 'branches', 'codescan_alerts', 'collaborators', \n'comments', 'commits', 'contributors', 'deployments', 'discussions', 'downloads', \n'environments', 'events', 'forks', 'git_refs', 'hooks', 'issues', 'issues_comments', \n'issues_events', 'labels', 'languages', 'milestones', 'network_events', \n'notifications', 'pending_invitations', 'projects', 'pulls', 'pulls_comments', \n'pulls_review_comments', 'releases', 'repository_advisories', 'secrets', \n'self_hosted_runners', 'stargazers', 'stargazers_with_dates', 'stats_contributors', \n'subscribers', 'tags', 'teams', 'top_paths', 'top_referrers', 'topics', 'variables', \n'watchers', 'workflow_runs', 'workflows']\n>>>\n>>> 'issues' in r\nTrue\n>>> issues = r['issues']\n>>> sorted(issues)\n[4, 5]\n>>> issue_obj = issues[4]\n>>> issue_obj\nIssue(title=\"Test Issue A\", number=4)\n>>> sorted([attr for attr in dir(issue_obj) if not attr.startswith('_')])  # doctest: +SKIP\n['CHECK_AFTER_INIT_FLAG', 'active_lock_reason', 'add_to_assignees', 'add_to_labels', \n'as_pull_request', 'assignee', 'assignees', 'body', 'closed_at', 'closed_by', \n'comments', 'comments_url', 'create_comment', 'create_reaction', 'created_at', \n'delete_labels', 'delete_reaction', 'edit', 'etag', 'events_url', 'get__repr__', \n'get_comment', 'get_comments', 'get_events', 'get_labels', 'get_reactions', \n'get_timeline', 'html_url', 'id', 'labels', 'labels_url', 'last_modified', 'lock', \n'locked', 'milestone', 'number', 'pull_request', 'raw_data', 'raw_headers', \n'remove_from_assignees', 'remove_from_labels', 'repository', 'setCheckAfterInitFlag', \n'set_labels', 'state', 'state_reason', 'title', 'unlock', 'update', 'updated_at', \n'url', 'user']\n>>> issue_obj.number\n4\n>>> issue_obj.state\n'open'\n>>> issue_obj.labels\n[Label(name=\"documentation\"), Label(name=\"enhancement\")]\n>>> # title of issue\n>>> issue_obj.title\n'Test Issue A'\n>>> # content of issue\n>>> issue_obj.body\n'Contents of Test Issue A'\n>>>\n>>> issue_obj.comments\n2\n>>>\n>>> list(issue_obj.get_comments())  # doctest: +NORMALIZE_WHITESPACE\n[IssueComment(user=NamedUser(login=\"thorwhalen\"), id=1801792378), \nIssueComment(user=NamedUser(login=\"thorwhalen\"), id=1801792855)]\n>>> issue_comment = issue_obj.get_comment(1801792378)\n>>> issue_comment.body\n'Comment 1 of Test Issue A'\n>>>\n>>> 'discussions' in r\nTrue\n>>> discussions = r['discussions']  # doctest: +SKIP\n>>> sorted(discussions)  # doctest: +SKIP\n[1, 2, 3]\n```\n\n\n## hub function\n\nThe high level function `hub` is the simplest way to get started. It's a\nfunction that takes a path to a github resource and returns a mapping to that\nresource. The mapping is lazy, so it's only when you access a key that the\nresource is actually fetched from github.\n\n```python\n>>> repositories = hub('thorwhalen')\n>>> 'hubcap' in repositories\nTrue\n>>> hubcap_repo = repositories['hubcap']\n>>>\n>>> repo = hub('thorwhalen/hubcap')\n>>> 'master' in repo\nTrue\n>>> master_files = repo['master']\n>>>\n>>> files = hub('thorwhalen/hubcap/master')\n>>> '/README.md' in files\nTrue\n>>> '/hubcap/' in files\nTrue\n>>> hubcap_files = files['/hubcap/']\n>>> '/hubcap/base.py' in hubcap_files\nTrue\n```\n\n### Access issues\n\n```python\n>>> issues = hub('thorwhalen/hubcap/issues')\n>>> 3 in issues  # there's a \"number 3\" issue\nTrue\n>>> issue = issues[3]\n>>> issue.title\n'Test Issue'\n>>> issue.body\n'This is just a test issue to test that hubcap can see it.\\r\\n'\n>>> issue.comments  # meaning \"number of comments\"\n1\n```\n\n### Access discussions\n\n```python\n>>> discussions = hub('thorwhalen/hubcap/discussions')  # doctest: +SKIP\n>>> # get a list of discussion (keys)\n>>> list(discussions)  # doctest: +SKIP\n[2, ...]\n>>> # the discussion 2 should be included in that list\n>>> 2 in discussions  # doctest: +SKIP\nTrue\n>>> discussion = discussions[2]   # doctest: +SKIP\n>>> discussion  # doctest: +SKIP\n{'number': 2,\n 'title': 'Root interface of hubcap',\n 'body': 'Every time I need to do something with `hubcap` ...',\n 'author': {'login': 'thorwhalen'},\n 'createdAt': '2023-11-07T09:30:59Z',\n 'updatedAt': '2023-12-05T08:25:39Z',\n 'comments': [{'body': 'Further it would be nice if we ...',\n   'author': 'thorwhalen',\n   'replies': []}]}\n>>> discussion['title']    # doctest: +SKIP\n'Root interface of hubcap'\n```\n\nHere's a nice trick for those want to download a discussion in a nice readable format, \nfor you, or some AI, to look through. \n\n```python \n>>> from hubcap import create_markdown_from_jdict\n>>> markdown_string = create_markdown_from_jdict(discussion)  # doctest: +SKIP\n>>> print(markdown_string)  # doctest: +SKIP\n# Root interface of hubcap\n<BLANKLINE>\nEvery time I need to do something with `hubcap` I need to look up how it works again. \n<BLANKLINE>\nThat's negative points\n```\n\n## GithubReader\n\nOne of the main classes is `GithubReader`. It's a mapping that connects to a\ngithub user or organization, and returns a mapping of repositories. The\nrepositories are also mappings, that return mappings of branches, and so on.\n\n```python\n>>> from hubcap import GithubReader\n>>> s = GithubReader('thorwhalen')  # connnecting to a particular user/organization\n>>> list(s)  # doctest: +SKIP\n['agen',\n 'aix',\n ...\n 'viral',\n 'wealth',\n 'wrapt']\n>>> 'a_non_existing_repository_name' in s\nFalse\n>>> 'hubcap' in s  # of course, this will be true, it's what you're using now!\nTrue\n>>> repo = s['hubcap']\n>>> list(repo)\n['master']\n>>> branch = repo['master']\n>>> list(branch)  # doctest: +NORMALIZE_WHITESPACE\n['/.gitattributes', '/.github/', '/.gitignore', '/LICENSE',\n'/README.md', '/docsrc/', '/hubcap/', '/misc/', '/setup.cfg', '/setup.py']\n>>> content = branch['/setup.cfg']\n>>> print(content[:32].decode())\n[metadata]\nname = hubcap\nversion\n\n>>> from hubcap import get_repository_info\n>>> info = get_repository_info('thorwhalen/hubcap')\n>>> list(info)  # doctest: +NORMALIZE_WHITESPACE\n['name', 'full_name', 'description', 'stargazers_count',\n'forks_count', 'watchers_count', 'html_url', 'last_commit_date']\n>>> info['name']\n'hubcap'\n>>> info['html_url']\n'https://github.com/thorwhalen/hubcap'\n>>> info['stargazers_count'] >= 1\nTrue\n```\n\nYou also have other useful objects, like `Issues`, `IssueComments`, `Discussions`, etc.   \n\n\n## github_repo_text_aggregate\n\n```python\n>>> owner_repo_files = github_repo_text_aggregate('thorwhalen/hubcap')  # doctest: +SKIP\n>>> markdown_output = github_repo_text_aggregate(owner_repo_files)  # doctest: +SKIP\n```\n\n\n# Recipes\n\n## Clone to temp folder and get store (mapping) of files\n\n```python\nfrom hubcap import git_clone, git_wiki_clone\nfrom dol import TextFiles, filt_iter, Pipe\n\nrepo_py_files = Pipe(\n    git_clone, TextFiles, filt_iter(filt=lambda x: x.endswith('.py'))\n)\nrepo_wiki_files = Pipe(git_wiki_clone, TextFiles)\n```\n\n```python\npy_files = repo_py_files('i2mint/dol')\nlen(py_files)\n# 37\n```\n\n```python\nwiki_files = repo_wiki_files('i2mint/dol')\nlist(wiki_files)\n# ['Recipes.md',\n#  'Critiques-and-their-comebacks.md',\n#  'Home.md',\n#  'Mapping-Views.md']\n```\n",
    "bugtrack_url": null,
    "license": "apache-2.0",
    "summary": "A py2store (i.e. dict-like) interface to github",
    "version": "0.1.7",
    "project_urls": {
        "Homepage": "https://github.com/thorwhalen/hubcap"
    },
    "split_keywords": [
        "github"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a1690fc2bc6d36ec3a4e3c267a7255e26fda8b0502492b850043b1c919aaab53",
                "md5": "36f55d13d4925bf9351a0e1313160679",
                "sha256": "57d2e0e8a1ce933205eae39715d1dc49c30d7869727dc069f9c779d27a3c26e1"
            },
            "downloads": -1,
            "filename": "hubcap-0.1.7.tar.gz",
            "has_sig": false,
            "md5_digest": "36f55d13d4925bf9351a0e1313160679",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 39256,
            "upload_time": "2024-11-15T13:34:28",
            "upload_time_iso_8601": "2024-11-15T13:34:28.261662Z",
            "url": "https://files.pythonhosted.org/packages/a1/69/0fc2bc6d36ec3a4e3c267a7255e26fda8b0502492b850043b1c919aaab53/hubcap-0.1.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-15 13:34:28",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "thorwhalen",
    "github_project": "hubcap",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "hubcap"
}
        
Elapsed time: 1.06073s