File: example.py

package info (click to toggle)
typedload 2.37-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 840 kB
  • sloc: python: 3,225; makefile: 146
file content (137 lines) | stat: -rwxr-xr-x 3,881 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python3

# typedload
# Copyright (C) 2020-2024 Salvo "LtWorf" Tomaselli
#
# typedload is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# author Salvo "LtWorf" Tomaselli <tiposchi@tiscali.it>


# This is a practical example on how to use the typedload library.
# It is a somewhat simple use case so most capabilities are not
# shown here.

# Json data is downloaded from the internet and then loaded into
# Python data structures (dictionaries, lists, strings, and so on).

#This example queries github API

import argparse
from datetime import datetime
from uuid import UUID
import json
from typing import *
import urllib.request

import typedload


class CommandLine(NamedTuple):
    full: bool
    project: Optional[str]
    username: Optional[str]

    def get_url(self) -> str:
        if self.username is None and self.project is None:
            username = 'ltworf'
            project = 'relational'
        elif self.username and self.project:
            username = self.username
            project = self.project
        else:
            raise ValueError('Username and project need to be set together')
        return f'https://codeberg.org/api/v1/repos/{username}/{project}/releases'


class User(NamedTuple):
    id: int
    login: str
    email: str
    created: datetime
    username: str


class Asset(NamedTuple):
    id: int
    name: str
    size: int
    download_count: int
    created_at: datetime
    uuid: UUID
    browser_download_url: str


class Release(NamedTuple):
    id: int
    tag_name: str
    name: str
    url: str
    html_url: str
    tarball_url: str
    zipball_url: str
    draft: bool
    prerelease: bool
    created_at: datetime
    published_at: datetime
    author: User
    assets: List[Asset]


def get_data(args: CommandLine) -> Any:
    """
    Use the github API to get releases information
    """
    req = urllib.request.Request(args.get_url())
    with urllib.request.urlopen(req) as f:
        return json.load(f)


def print_report(data: List[Release], args: CommandLine):
    for i in data:
        if i.draft or i.prerelease:
            continue
        print('Release:', i.name, end=' ')

        if args.full:
            print('Created by:', i.author.login, 'on:', i.created_at)
        else:
            print()

        for asset in i.assets:
            if asset.download_count or args.full:
                print('\t%d\t%s' % (asset.download_count, asset.name))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--username', help='The username to query')
    parser.add_argument('-p', '--project', help='The project to query')
    parser.add_argument('-f', '--full', help='Print the full report', action='store_true')

    # We load the args into a NamedTuple, so it is no longer an obscure dynamic object but it is typed
    args = typedload.load(parser.parse_args(), CommandLine)
    data = get_data(args)

    # Github returns dates like this "2016-08-23T18:26:00Z", which are not supported by typedload
    # So we make a custom handler for them.
    loader = typedload.dataloader.Loader()

    # We know what the API returns so we can load the json into typed data
    typed_data = loader.load(data, List[Release])
    print_report(typed_data, args)


if __name__ == '__main__':
    main()