Skip to content

Commit 6505749

Browse files
authored
Merge pull request #149 from MerleLiuKun/feat-usage
Feat usage
2 parents 739941d + 0ccf479 commit 6505749

File tree

11 files changed

+129
-1
lines changed

11 files changed

+129
-1
lines changed

README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ Now covers these features:
124124
- Direct Messages lookup
125125
- Manage Direct Messages
126126

127+
- Usage
128+
- Tweets
129+
127130
- Media Upload
128131
- Media Simple upload
129132
- Media Chunked upload

docs/docs/usage/usage/tweets.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The Usage API in the Twitter API v2 allows developers to programmatically retrieve their project usage. Using thie endpoint, developers can keep a track and monitor of the number of Tweets they have pulled for a given billing cycle.
2+
3+
You can learn more about the Usage API in the [docs](https://developer.twitter.com/en/docs/twitter-api/usage/tweets/introduction).
4+
5+
!!! tip "Note"
6+
7+
The Usage API need `OAuth 2.0 App-only`.
8+
9+
### Get usage
10+
11+
Get the Tweet usage within the context of a project
12+
13+
```python
14+
from pytwitter import Api
15+
16+
api = Api(bearer_token='your bearer token')
17+
18+
resp = api.get_usage_tweets(days=10, usage_fields=["daily_client_app_usage", "daily_project_usage"])
19+
print(resp.data)
20+
# Usage(cap_reset_day=28, project_id='123456789', project_cap='50000000', project_usage='11910737',...)
21+
```

docs/mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ nav:
6868
- Direct Messages:
6969
- Direct Messages lookup: usage/direct-messages/direct-messages-lookup.md
7070
- Manage Direct Messages: usage/direct-messages/manage-direct-messages.md
71+
- Usage:
72+
- Tweets: usage/usage/tweets.md
7173
- Steaming: usage/streaming.md
7274
- Changelog: CHANGELOG.md
7375

pytwitter/api.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ def _get(
451451
errors=[md.Error.new_from_json_dict(err) for err in errors]
452452
if errors is not None
453453
else None,
454+
_json=resp_json,
454455
)
455456
return res
456457

@@ -3257,3 +3258,34 @@ def create_conversation(
32573258
if return_json
32583259
else md.DirectMessageCreateResponse.new_from_json_dict(data["data"])
32593260
)
3261+
3262+
def get_usage_tweets(
3263+
self,
3264+
*,
3265+
days: Optional[int] = None,
3266+
usage_fields: Optional[Union[str, List, Tuple]] = None,
3267+
return_json: bool = False,
3268+
) -> Union[dict, md.Response]:
3269+
"""
3270+
Get the Tweet usage within the context of a project
3271+
3272+
Note: This need OAuth2.0 App-only auth.
3273+
3274+
:param days: The number of days for which you need the Tweet usage for. Up to 90 days.
3275+
:param usage_fields: Fields for the usage.
3276+
:param return_json: Type for returned data. If you set True JSON data will be returned.
3277+
:return: Usage data response.
3278+
"""
3279+
args = {
3280+
"days": days,
3281+
"usage.fields": enf_comma_separated(
3282+
name="usage_fields",
3283+
value=usage_fields,
3284+
),
3285+
}
3286+
return self._get(
3287+
url=f"{self.BASE_URL_V2}/usage/tweets",
3288+
params=args,
3289+
cls=md.Usage,
3290+
return_json=return_json,
3291+
)

pytwitter/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
from .list import * # noqa
1010
from .stream import * # noqa
1111
from .dm_event import * # noqa
12+
from .usage import * # noqa
1213
from .ext import * # noqa

pytwitter/models/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ def new_from_json_dict(
2929
return None
3030
c = cls.from_dict(data, infer_missing=infer_missing)
3131
# save origin data
32-
cls._json = data
32+
c._json = data
3333
return c

pytwitter/models/ext.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
ComplianceJob,
2020
StreamRule,
2121
TwitterList,
22+
Usage,
2223
)
2324

2425

@@ -110,6 +111,7 @@ class Response:
110111
ComplianceJob,
111112
TwitterList,
112113
DirectMessageEvent,
114+
Usage,
113115
List[User],
114116
List[Tweet],
115117
List[Media],
@@ -126,3 +128,5 @@ class Response:
126128
includes: Optional[Includes] = field(default=None, repr=False)
127129
meta: Optional[Meta] = field(default=None, repr=False)
128130
errors: Optional[List[Error]] = field(default=None, repr=False)
131+
# inline field to keep origin response json data
132+
_json: Optional[dict] = field(default=None, repr=False)

pytwitter/models/usage.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
Usage object
3+
Refer:https://developer.twitter.com/en/docs/twitter-api/usage/tweets/api-reference/get-usage-tweets
4+
"""
5+
6+
from dataclasses import dataclass, field
7+
from typing import Optional, List
8+
9+
from .base import BaseModel
10+
11+
12+
@dataclass
13+
class UsageUsage(BaseModel):
14+
date: Optional[str] = field(default=None)
15+
usage: Optional[str] = field(default=None)
16+
17+
18+
@dataclass
19+
class DailyProjectUsage(BaseModel):
20+
project_id: Optional[str] = field(default=None)
21+
usage: Optional[List[UsageUsage]] = field(default=None, repr=False)
22+
23+
24+
@dataclass
25+
class DailyClientAppUsage(BaseModel):
26+
client_app_id: Optional[str] = field(default=None)
27+
usage_result_count: Optional[int] = field(default=None)
28+
usage: Optional[List[UsageUsage]] = field(default=None, repr=False)
29+
30+
31+
@dataclass
32+
class Usage(BaseModel):
33+
cap_reset_day: Optional[int] = field(default=None)
34+
project_id: Optional[str] = field(default=None)
35+
project_cap: Optional[str] = field(default=None)
36+
project_usage: Optional[str] = field(default=None)
37+
daily_project_usage: Optional[DailyProjectUsage] = field(default=None, repr=False)
38+
daily_client_app_usage: Optional[List[DailyClientAppUsage]] = field(
39+
default=None, repr=False
40+
)

pytwitter/rate_limit.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,12 @@ def get_limit(self, auth_type, method="GET"):
364364
LIMIT_APP_GET=200,
365365
)
366366

367+
USAGE_TWEETS = Endpoint(
368+
resource="/usage/tweets",
369+
regex=re.compile(r"/usage/tweets"),
370+
LIMIT_APP_GET=50,
371+
)
372+
367373
MEDIA_UPLOAD = Endpoint(
368374
resource="/media/upload.json",
369375
regex=re.compile(r"/media/upload.json"),
@@ -425,6 +431,7 @@ def get_limit(self, auth_type, method="GET"):
425431
DM_MESSAGE_TO_PARTICIPANT,
426432
DM_MESSAGE_TO_CONVERSATION,
427433
DM_CONVERSATIONS,
434+
USAGE_TWEETS,
428435
MEDIA_UPLOAD,
429436
]
430437

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"data":{"cap_reset_day":28,"project_cap":"50000000","project_id":"123457578435","project_usage":"11174038"}}

0 commit comments

Comments
 (0)