Skip to content

Commit 7965194

Browse files
authored
Merge pull request #8 from nnnLik/feature/refactor-admitad-api
- Add PromoOffersForCampaign support and modernize codebase - Add PromoOffersForCampaign class for campaign promo offers retrieval - Refactor Client and Exception classes to use dataclasses - Pin requests dependency to 2.32.5 for stability - Add comprehensive test coverage for new functionality - Improve type safety with enhanced type hints - Support custom API base URL via environment variable
2 parents a8179ee + 84a006b commit 7965194

30 files changed

+243
-219
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*.so
55

66
# Packages
7+
.eggs
78
*.egg
89
*.egg-info
910
dist
@@ -33,7 +34,7 @@ nosetests.xml
3334
.mr.developer.cfg
3435
.project
3536
.pydevproject
36-
37+
.venv
3738
.idea
3839
*.sublime*
3940

admitad/api.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
3-
41
from admitad import client, transport
52

63

7-
def get_oauth_client_token(access_token, user_agent=None, debug=False):
8-
"""
9-
Creates a client using an access token.
10-
11-
"""
12-
http_transport = transport.HttpTransport(access_token, user_agent=user_agent, debug=debug)
4+
def get_oauth_client_token(
5+
access_token: str,
6+
user_agent: str | None = None,
7+
debug: bool = False,
8+
) -> client.Client:
9+
"""Creates a client using an access token."""
10+
http_transport = transport.HttpTransport(
11+
access_token,
12+
user_agent=user_agent,
13+
debug=debug,
14+
)
1315
return client.Client(http_transport)
1416

1517

16-
def get_oauth_client_client(client_id, client_secret, scopes, user_agent=None, debug=False):
17-
"""
18-
Creates a client using a client_id and client_secret.
19-
20-
"""
18+
def get_oauth_client_client(
19+
client_id: str,
20+
client_secret: str,
21+
scopes: str,
22+
user_agent: str | None = None,
23+
debug: bool = False,
24+
) -> client.Client:
25+
"""Creates a client using a client_id and client_secret."""
2126
auth = transport.oauth_client_authorization({
2227
'client_id': client_id,
2328
'client_secret': client_secret,
2429
'scopes': scopes
2530
})
26-
return get_oauth_client_token(auth['access_token'], user_agent=user_agent, debug=debug)
31+
32+
return get_oauth_client_token(
33+
auth['access_token'],
34+
user_agent=user_agent,
35+
debug=debug,
36+
)

admitad/client.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
1+
from dataclasses import dataclass
32

4-
from admitad import items
3+
from admitad import items, transport
54

65

7-
class Client(object):
8-
"""The API client."""
6+
@dataclass
7+
class Client:
8+
_transport: transport.HttpTransport
99

10-
def __init__(self, transport):
11-
self.transport = transport
12-
13-
def __getattr__(self, name):
14-
return getattr(items, name)(self.transport)
10+
def __getattr__(self, name: str) -> type[items.Item]:
11+
return getattr(items, name)(self._transport)

admitad/constants.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
1+
import os
32

4-
# API date-format
5-
DATE_FORMAT = '%d.%m.%Y'
6-
LONG_DATE_FORMAT = '%d.%m.%Y %H:%M:%S'
3+
DATE_FORMAT: str = '%d.%m.%Y'
4+
LONG_DATE_FORMAT: str = '%d.%m.%Y %H:%M:%S'
75

8-
SUPPORTED_LANGUAGES = ('ru', 'en', 'de', 'pl', 'es', 'tr')
6+
SUPPORTED_LANGUAGES: tuple[str, ...] = ('ru', 'en', 'de', 'pl', 'es', 'tr')
97

10-
# default values
11-
DEFAULT_REQUEST_TIMEOUT = 60
12-
DEFAULT_LANGUAGE = 'ru'
13-
DEFAULT_PAGINATION_LIMIT = 20
14-
DEFAULT_PAGINATION_OFFSET = 0
8+
DEFAULT_REQUEST_TIMEOUT: int = 60
9+
DEFAULT_LANGUAGE: str = 'ru'
10+
DEFAULT_PAGINATION_LIMIT: int = 20
11+
DEFAULT_PAGINATION_OFFSET: int = 0
1512

16-
# constants
17-
MAX_PAGINATION_LIMIT = 500
18-
MAX_SUB_ID_LENGTH = 250
13+
MAX_PAGINATION_LIMIT: int = 500
14+
MAX_SUB_ID_LENGTH: int = 250
1915

20-
# urls
21-
BASE_URL = 'https://api.admitad.com/'
22-
AUTHORIZE_URL = '%s%s' % (BASE_URL, 'authorize/')
23-
TOKEN_URL = '%s%s' % (BASE_URL, 'token/')
16+
DEFAULT_PROD_URL: str = 'https://api.admitad.com/'
17+
CUSTOM_BASE_URL: str = os.getenv('ADMITAD_API_LIB_BASE_URL')
18+
19+
BASE_URL: str = (CUSTOM_BASE_URL or DEFAULT_PROD_URL).rstrip('/') + '/'
20+
AUTHORIZE_URL: str = f'{BASE_URL}authorize/'
21+
TOKEN_URL: str = f'{BASE_URL}token/'

admitad/exceptions.py

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,34 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
1+
from dataclasses import dataclass
32

43

4+
@dataclass
55
class HttpException(Exception):
6+
status: int
7+
message: str
8+
content: str
69

7-
def __init__(self, status, message, content):
8-
super(HttpException, self).__init__()
9-
10-
self.status = status
11-
self.message = message
12-
self.content = content
13-
14-
def __str__(self):
15-
return repr(self)
16-
17-
def __repr__(self):
18-
return "HttpException(%s): %s%s" % (
19-
self.status, self.content,
20-
"\n%s" % self.message if self.message else "")
21-
10+
def __str__(self) -> str:
11+
return f"HttpException({self.status}): {self.message}\n{self.content}"
2212

13+
@dataclass
2314
class ConnectionException(Exception):
15+
content: str
2416

25-
def __init__(self, content):
26-
super(ConnectionException, self).__init__()
27-
28-
self.content = content
29-
30-
def __str__(self):
31-
return repr(self)
32-
33-
def __repr__(self):
34-
return "ConnectionException: %s" % self.content
17+
def __str__(self) -> str:
18+
return f"ConnectionException: {self.content}"
3519

3620

21+
@dataclass
3722
class JsonException(Exception):
23+
content: str
3824

39-
def __init__(self, content):
40-
super(JsonException, self).__init__()
41-
42-
self.content = content
43-
44-
def __str__(self):
45-
return repr(self)
46-
47-
def __repr__(self):
48-
return "JsonException: %s" % self.content
25+
def __str__(self) -> str:
26+
return f"JsonException: {self.content}"
4927

5028

29+
@dataclass
5130
class ApiException(Exception):
31+
content: str
5232

53-
def __init__(self, content):
54-
super(ApiException, self).__init__()
55-
56-
self.content = content
57-
58-
def __str__(self):
59-
return repr(self)
60-
61-
def __repr__(self):
62-
return "ApiException: %s" % self.content
33+
def __str__(self) -> str:
34+
return f"ApiException: {self.content}"

admitad/items/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
from admitad.items.retag import *
1818
from admitad.items.broken_links import *
1919
from admitad.items.tickets import *
20+
from admitad.items.promo_offers import *

admitad/items/announcements.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
3-
41
from admitad.items.base import Item
52

63

admitad/items/auxiliary.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
3-
41
from admitad.items.base import Item
52

63

admitad/items/banners.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
3-
41
from admitad.items.base import Item
52

63

admitad/items/base.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
# coding: utf-8
2-
from __future__ import unicode_literals
3-
4-
from future import standard_library
5-
standard_library.install_aliases()
6-
7-
from future.builtins import int, str
81
from datetime import datetime, date
92
from urllib.parse import urljoin
103

114
from admitad.constants import BASE_URL, DATE_FORMAT, LONG_DATE_FORMAT
5+
from admitad.transport import HttpTransport
126

137

14-
class Item(object):
8+
class Item:
159

16-
def __init__(self, transport):
10+
def __init__(self, transport: HttpTransport):
1711
self.transport = transport
1812
self.transport.clean_data()
1913

0 commit comments

Comments
 (0)