├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── dadata ├── __init__.py ├── client.py ├── plugins │ ├── __init__.py │ └── django.py └── version.py ├── requirements.txt ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── common.py ├── test_address.py ├── test_client_defaults.py ├── test_connect.py ├── test_django.py ├── test_suggestions.py └── test_url_builder.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *.egg-info 4 | .eggs 5 | build/* 6 | src/* 7 | *.pyc 8 | .cache 9 | *.egg 10 | .idea 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.4" 4 | - "3.5" 5 | # - "2.7" 6 | #- "3.5-dev" # 3.5 development branch 7 | #- "3.6" 8 | #- "3.6-dev" # 3.6 development branch 9 | #- "3.7-dev" # 3.7 development branch 10 | #- "nightly" # currently points to 3.7-dev 11 | # command to install dependencies 12 | install: 13 | - python3 setup.py build 14 | # command to run tests 15 | script: 16 | - python3 setup.py test 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nikolay Fominykh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unofficial Python dadata.ru Client [![Build Status](https://travis-ci.org/tigrus/dadata-python.svg?branch=master)](https://travis-ci.org/tigrus/dadata-python) 2 | =============================================== 3 | 4 | ## Install 5 | 6 | ``` 7 | $ pip install -e git+https://github.com/tigrus/dadata-python#egg=dadata 8 | ``` 9 | 10 | ## Usage 11 | 12 | ``` 13 | >>> from dadata import DaDataClient 14 | >>> client = DaDataClient( 15 | key = '', 16 | secret = '', 17 | ) 18 | 19 | >>> # You can assign one address 20 | >>> client.address = "мск сухонска 11/-89" 21 | 22 | >>> # You can assign multiple addresses 23 | >>> client.address = ["мск сухонска 11/-89", "спб невский 18"] 24 | 25 | >>> #Now let's perform request.. 26 | >>> client.address.request() 27 | 28 | >>> #Now we will have first result in `client.result` 29 | >>> client.result.region_kladr_id 30 | '7700000000000' 31 | 32 | >>> #However we can reprocess data by our own desire - result from API saved in 33 | >>> client.response.content 34 | ``` 35 | 36 | ## Usage With Django 37 | 38 | In `settings.py`: 39 | ``` 40 | DADATA_KEY = "" 41 | DADATA_SECRET = "" 42 | ``` 43 | 44 | In project: 45 | ``` 46 | >>> from dadata.plugins.django import DjangoDaDataClient 47 | >>> client = DjangoDaDataClient() 48 | 49 | >>> # Now using as regular client.. 50 | >>> client.address = "мск сухонска 11/-89" 51 | ... 52 | ``` 53 | 54 | ## Suggestions Usage 55 | 56 | 57 | ``` 58 | >>> client.suggest_address = "194292, Санкт-Петербург г, 1-й Верхний пер, дом № 12, литера Б" 59 | >>> client.suggestions.address.request() 60 | >>> # Now we have list of suggestions in client.result 61 | >>> client.result.suggestions[0].get('data').get('kladr_id') 62 | '7800000000015870028' 63 | ``` 64 | -------------------------------------------------------------------------------- /dadata/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import * 2 | 3 | -------------------------------------------------------------------------------- /dadata/client.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | import requests 3 | import json 4 | from copy import deepcopy 5 | 6 | 7 | """ 8 | Ограничения: 9 | не более 1 ФИО, 10 | 3 адресов, 11 | 3 телефонов, 12 | 3 email 13 | """ 14 | EMAIL_LIMIT = 3 15 | PHONE_LIMIT = 3 16 | ADDRESS_LIMIT = 3 17 | FIO_LIMIT = 1 18 | PASSPORT_LIMIT = 1 19 | DATE_LIMIT = 1 20 | AUTO_LIMIT = 1 21 | SUGGESTIONS_LIMIT = 1 22 | 23 | 24 | """ 25 | Методы Стандартизации 26 | """ 27 | CLEAN_NAMES = ['address', 'phone', 'passport', 'fio', 'email', 'auto', 'date'] 28 | 29 | 30 | """ 31 | Constants & Errors 32 | """ 33 | SUCCESS = 200 34 | 35 | LIMIT_ERROR = 'Ограничение превышено. Введено %s значений из %s' 36 | 37 | class Errors: 38 | CLIENT_NO_KEY = 600 39 | CLIENT_NO_SECRET = 601 40 | CLIENT_NO_DATA = 602 41 | 42 | """ 43 | Exceptions 44 | """ 45 | class LimitExceed(Exception): 46 | pass 47 | 48 | 49 | """ 50 | Helper Mixins 51 | """ 52 | class ManyOneMixin(object): 53 | def _get_one(self): 54 | return self.client.data[0] if self.client.data else None 55 | 56 | def _set_one(self, value): 57 | self.client.data = [] 58 | self.client.data.append(value) 59 | 60 | one = property(_get_one, _set_one) 61 | 62 | def _get_many(self): 63 | return self.client.data 64 | 65 | def _set_many(self, value): 66 | self.client.data = [] 67 | if len(value) > self.limit: 68 | raise LimitExceed(LIMIT_ERROR % (len(value), self.limit)) 69 | self.client.data.extend(value) 70 | 71 | many = property(_get_many, _set_many) 72 | 73 | 74 | class QueryMixin(object): 75 | def _get_query(self): 76 | return self.client.data 77 | 78 | def _set_query(self, value): 79 | self.client.data = {'query': value} 80 | 81 | query = property(_get_query, _set_query) 82 | 83 | 84 | """ 85 | Обертка над Dadata API 86 | """ 87 | class Result(object): 88 | def __init__(self, **kwargs): 89 | self.__dict__.update(kwargs) 90 | 91 | 92 | class ApiURL(ManyOneMixin, QueryMixin): 93 | limit = 1 94 | url = '' 95 | private = True 96 | 97 | def __init__(self, **kwargs): 98 | for key, value in kwargs.items(): 99 | setattr(self, key, value) 100 | self.url += self.url_postfix 101 | 102 | def request(self): 103 | return self.client.request(self) 104 | 105 | def process_result(self, client): 106 | result = Result(**client._result[0]) 107 | return result 108 | 109 | def update(self, value): 110 | if self.private: 111 | if isinstance(value, list): 112 | self.many = value 113 | else: 114 | self.one = value 115 | else: 116 | self.query = value 117 | 118 | 119 | class SuggestionApiURL(ApiURL): 120 | def process_result(self, client): 121 | result = Result(**client._result) 122 | return result 123 | 124 | 125 | """ 126 | Clean API 127 | """ 128 | class Clean(ApiURL): 129 | url_postfix = '/clean' 130 | 131 | def __init__(self, *args, **kwargs): 132 | super(Clean, self).__init__(*args, **kwargs) 133 | kwargs['url'] = self.url 134 | self.address = Address(**kwargs) 135 | self.phone = Phone(**kwargs) 136 | self.passport = Passport(**kwargs) 137 | self.fio = FIO(**kwargs) 138 | self.email = EMail(**kwargs) 139 | self.date = Date(**kwargs) 140 | self.auto = Auto(**kwargs) 141 | 142 | 143 | 144 | """ 145 | Clean Entities 146 | """ 147 | class Address(ApiURL): 148 | url_postfix = '/address' 149 | limit = ADDRESS_LIMIT 150 | 151 | 152 | class Phone(ApiURL): 153 | url_postfix = '/phone' 154 | limit = PHONE_LIMIT 155 | 156 | 157 | class Passport(ApiURL): 158 | url_postfix = '/passport' 159 | limit = PASSPORT_LIMIT 160 | 161 | 162 | class FIO(ApiURL): 163 | url_postfix = '/name' 164 | limit = FIO_LIMIT 165 | 166 | 167 | class EMail(ApiURL): 168 | url_postfix = '/email' 169 | limit = EMAIL_LIMIT 170 | 171 | 172 | class Date(ApiURL): 173 | url_postfix = '/birthdate' 174 | limit = DATE_LIMIT 175 | 176 | 177 | class Auto(ApiURL): 178 | url_postfix = '/vehicle' 179 | limit = AUTO_LIMIT 180 | 181 | 182 | """ 183 | Suggestion API 184 | """ 185 | class Suggestions(ApiURL): 186 | url_postfix = "/suggest" 187 | 188 | def __init__(self, *args, **kwargs): 189 | super(Suggestions, self).__init__(*args, **kwargs) 190 | kwargs['url'] = self.url 191 | kwargs['private'] = False 192 | self.address = S_Address(**kwargs) 193 | self.fio = S_FIO(**kwargs) 194 | self.email = S_EMail(**kwargs) 195 | self.organization = S_Party(**kwargs) 196 | self.bank = S_Bank(**kwargs) 197 | 198 | 199 | """ 200 | Suggestion Entities 201 | """ 202 | class S_Address(SuggestionApiURL): 203 | url_postfix = '/address' 204 | limit = ADDRESS_LIMIT 205 | 206 | 207 | class S_Party(SuggestionApiURL): 208 | url_postfix = '/party' 209 | limit = SUGGESTIONS_LIMIT 210 | 211 | 212 | class S_Bank(SuggestionApiURL): 213 | url_postfix = '/bank' 214 | limit = SUGGESTIONS_LIMIT 215 | 216 | 217 | class S_FIO(SuggestionApiURL): 218 | url_postfix = '/name' 219 | limit = FIO_LIMIT 220 | 221 | 222 | class S_EMail(SuggestionApiURL): 223 | url_postfix = '/email' 224 | limit = EMAIL_LIMIT 225 | 226 | 227 | """ 228 | Client.. 229 | """ 230 | class DaDataClient(object): 231 | url = 'https://dadata.ru/api/v2' 232 | suggestions_url = 'https://dadata.ru/api/v2' 233 | key = '' 234 | secret = '' 235 | data = [] 236 | result = None 237 | 238 | def __init__(self, *args, **kwargs): 239 | for key, value in kwargs.items(): 240 | setattr(self, key, value) 241 | 242 | self.clean = Clean( 243 | url = self.url, 244 | client = self, 245 | ) 246 | 247 | self.suggestions = Suggestions( 248 | url = self.suggestions_url, 249 | client = self, 250 | ) 251 | 252 | self.session = requests.Session() 253 | 254 | def __getattr__(self, name): 255 | if name in CLEAN_NAMES: 256 | return getattr(self.clean, name) 257 | tokens = name.split('_') 258 | 259 | if len(tokens) == 2: 260 | point, method = tokens 261 | if point == 'suggest': 262 | return getattr(self.suggestions, method) 263 | 264 | return super(DaDataClient, self).__getattr__(name) 265 | 266 | def __setattr__(self, name, value): 267 | if name in CLEAN_NAMES: 268 | return self.clean.__dict__[name].update(value) 269 | 270 | tokens = name.split('_') 271 | if len(tokens) == 2: 272 | point, method = tokens 273 | if point == 'suggest': 274 | return self.suggestions.__dict__[method].update(value) 275 | 276 | return super(DaDataClient, self).__setattr__(name, value) 277 | 278 | def request(self, api_method=None): 279 | # TODO: Rethink.. 280 | if not self.key: 281 | return Errors.CLIENT_NO_KEY 282 | # if not self.secret: 283 | # return Errors.CLIENT_NO_SECRET 284 | if not self.data: 285 | return Errors.CLIENT_NO_DATA 286 | 287 | headers={ 288 | 'Authorization': 'Token %s' % self.key, 289 | 'Content-Type': 'application/json', 290 | } 291 | 292 | if api_method.private: 293 | headers['X-Secret'] = self.secret 294 | 295 | response = self.session.post(api_method.url, 296 | data=json.dumps(self.data), 297 | headers=headers) 298 | 299 | if not response.status_code == SUCCESS: 300 | return response.status_code 301 | 302 | self._result = json.loads(response.content.decode('utf-8')) 303 | self.result = api_method.process_result(self) 304 | self.response = response 305 | return SUCCESS 306 | 307 | 308 | -------------------------------------------------------------------------------- /dadata/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | from .django import DjangoDaDataClient 2 | 3 | -------------------------------------------------------------------------------- /dadata/plugins/django.py: -------------------------------------------------------------------------------- 1 | # coding : utf-8 2 | from __future__ import absolute_import 3 | 4 | from dadata import DaDataClient 5 | 6 | 7 | def get_settings(): 8 | from django.conf import settings 9 | return settings 10 | 11 | 12 | class DjangoDaDataClient(DaDataClient): 13 | def __init__(self, *args, **kwargs): 14 | settings = get_settings() 15 | super(DjangoDaDataClient, self).__init__( 16 | key=settings.DADATA_KEY, 17 | secret=settings.DADATA_SECRET, 18 | ) 19 | -------------------------------------------------------------------------------- /dadata/version.py: -------------------------------------------------------------------------------- 1 | __version_info__ = (0, 1, 4) 2 | __version__ = ".".join(map(str, __version_info__)) 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup 3 | 4 | def read(fname): 5 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 6 | 7 | exec(open('dadata/version.py').read()) 8 | 9 | setup( 10 | name = "dadata-client", 11 | version = __version__, 12 | author = "Nikolay Fominykh", 13 | author_email = "nikolayfn@gmail.com", 14 | description = ("DaData Python Client"), 15 | license = "MIT", 16 | keywords = "dadata api-client", 17 | # url = "http://packages.python.org/an_example_pypi_project", 18 | packages=[ 19 | 'dadata', 20 | 'dadata.plugins' 21 | ], 22 | install_requires=[ 23 | 'requests', 24 | # 'nosetests', 25 | ], 26 | setup_requires=[ 27 | 'pytest-runner', 28 | ], 29 | long_description=read('README.md'), 30 | # test_suite='pytest', 31 | tests_require=['pytest', 'mock', 'pytest-runner', 'requests-mock' ], 32 | classifiers=[ 33 | "Development Status :: 3 - Alpha", 34 | "Topic :: Utilities", 35 | "License :: OSI Approved :: BSD License", 36 | ], 37 | ) 38 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigrus/dadata-python/614bc9a765d9401cef12b1b07364c1f98ea81c10/tests/__init__.py -------------------------------------------------------------------------------- /tests/common.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from dadata import DaDataClient 3 | 4 | 5 | class CommonTestCase(unittest.TestCase): 6 | def setUp(self): 7 | self.client = DaDataClient() 8 | self.client_with_key = DaDataClient(key="anykey") 9 | self.client_with_key_secret = DaDataClient(key="anykey", secret="anysec") 10 | -------------------------------------------------------------------------------- /tests/test_address.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | """ 4 | Здесь будем проверять запросы к ресурсу типа адрес 5 | """ 6 | import json 7 | import requests_mock 8 | 9 | from .common import CommonTestCase 10 | from dadata import DaDataClient 11 | 12 | ADDRESS_REQUEST = "мск сухонска 11/-89" 13 | 14 | ADDRESS_RESPONSE = """[ 15 | { 16 | "source": "мск сухонска 11/-89", 17 | "result": "г Москва, ул Сухонская, д 11, кв 89", 18 | "postal_code": "127642", 19 | "country": "Россия", 20 | "region_fias_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5", 21 | "region_kladr_id": "7700000000000", 22 | "region_with_type": "г Москва", 23 | "region_type": "г", 24 | "region_type_full": "город", 25 | "region": "Москва", 26 | "area_fias_id": null, 27 | "area_kladr_id": null, 28 | "area_with_type": null, 29 | "area_type": null, 30 | "area_type_full": null, 31 | "area": null, 32 | "city_fias_id": null, 33 | "city_kladr_id": null, 34 | "city_with_type": null, 35 | "city_type": null, 36 | "city_type_full": null, 37 | "city": null, 38 | "city_area": "Северо-восточный", 39 | "city_district_fias_id": null, 40 | "city_district_kladr_id": null, 41 | "city_district_with_type": "р-н Северное Медведково", 42 | "city_district_type": "р-н", 43 | "city_district_type_full": "район", 44 | "city_district": "Северное Медведково", 45 | "settlement_fias_id": null, 46 | "settlement_kladr_id": null, 47 | "settlement_with_type": null, 48 | "settlement_type": null, 49 | "settlement_type_full": null, 50 | "settlement": null, 51 | "street_fias_id": "95dbf7fb-0dd4-4a04-8100-4f6c847564b5", 52 | "street_kladr_id": "77000000000283600", 53 | "street_with_type": "ул Сухонская", 54 | "street_type": "ул", 55 | "street_type_full": "улица", 56 | "street": "Сухонская", 57 | "house_fias_id": "5ee84ac0-eb9a-4b42-b814-2f5f7c27c255", 58 | "house_kladr_id": "7700000000028360004", 59 | "house_type": "д", 60 | "house_type_full": "дом", 61 | "house": "11", 62 | "block_type": null, 63 | "block_type_full": null, 64 | "block": null, 65 | "flat_type": "кв", 66 | "flat_type_full": "квартира", 67 | "flat": "89", 68 | "flat_area": "34.6", 69 | "square_meter_price": "198113", 70 | "flat_price": "6854710", 71 | "postal_box": null, 72 | "fias_id": "5ee84ac0-eb9a-4b42-b814-2f5f7c27c255", 73 | "fias_level": "8", 74 | "kladr_id": "7700000000028360004", 75 | "capital_marker": "0", 76 | "okato": "45280583000", 77 | "oktmo": "45362000", 78 | "tax_office": "7715", 79 | "tax_office_legal": null, 80 | "timezone": "UTC+3", 81 | "geo_lat": "55.8785292", 82 | "geo_lon": "37.6536442", 83 | "beltway_hit": "IN_MKAD", 84 | "beltway_distance": null, 85 | "qc_geo": 0, 86 | "qc_complete": 0, 87 | "qc_house": 2, 88 | "qc": 0, 89 | "unparsed_parts": null 90 | }]""" 91 | 92 | 93 | class AddressRequestTest(CommonTestCase): 94 | def setUp(self): 95 | self.client = DaDataClient( 96 | url="mock://api/v2", 97 | key="key", 98 | secret="secret", 99 | ) 100 | adapter = requests_mock.Adapter() 101 | adapter.register_uri('POST', 102 | 'mock://api/v2/clean/address', 103 | request_headers={'Authorization': 'Token key', 'X-Secret':'secret'}, 104 | text=ADDRESS_RESPONSE) 105 | self.client.session.mount('mock', adapter) 106 | 107 | def test_address_request(self): 108 | self.client.address = ADDRESS_REQUEST 109 | code = self.client.address.request() 110 | self.assertEqual(code, 200) 111 | result = self.client.result 112 | self.assertEqual(result.region_kladr_id, "7700000000000") 113 | -------------------------------------------------------------------------------- /tests/test_client_defaults.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | Проверяем конфигурируемость клиента 4 | """ 5 | import unittest 6 | from .common import CommonTestCase 7 | from dadata import DaDataClient 8 | 9 | 10 | class DefaultsTest(CommonTestCase): 11 | def test_url(self): 12 | self.assertEqual(self.client.url, self.client.url) 13 | 14 | def test_url_override(self): 15 | client = DaDataClient(url='http://myurl') 16 | self.assertEqual(client.url, 'http://myurl') 17 | -------------------------------------------------------------------------------- /tests/test_connect.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | Тестового варианта доступа не существует, поэтому проверим отказ в доступе. 4 | """ 5 | from .common import CommonTestCase 6 | 7 | 8 | class DenyTest(CommonTestCase): 9 | def test_that_client_has_session(self): 10 | self.assertTrue(self.client.session) 11 | -------------------------------------------------------------------------------- /tests/test_django.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from .common import CommonTestCase 3 | from mock import patch, MagicMock 4 | import dadata.plugins.django 5 | 6 | """ 7 | Monkey Patching. 8 | """ 9 | def get_settings(): 10 | class Settings(object): 11 | pass 12 | s = Settings() 13 | s.DADATA_KEY = "key" 14 | s.DADATA_SECRET = "secret" 15 | return s 16 | 17 | dadata.plugins.django.get_settings = get_settings 18 | 19 | class DjangoTest(CommonTestCase): 20 | """ 21 | Проверяем, что создан клиент с настройками от django 22 | """ 23 | @patch('dadata.plugins.django.get_settings', get_settings) 24 | def test_django_init(self): 25 | client = dadata.plugins.django.DjangoDaDataClient() 26 | self.assertEqual(client.key, "key") 27 | -------------------------------------------------------------------------------- /tests/test_suggestions.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from .common import CommonTestCase 3 | 4 | 5 | class SuggestionsTest(CommonTestCase): 6 | def test_suggestion_url(self): 7 | client = self.client 8 | # self.assertEqual(client.suggestions.address.url, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address") 9 | self.assertEqual(client.suggestions.address.url, "https://dadata.ru/api/v2/suggest/address") 10 | 11 | def test_that_suggestion_url_is_not_private(self): 12 | self.assertEqual(self.client.suggestions.address.private, False) 13 | 14 | def test_that_assigned_data_is_query(self): 15 | self.client.suggest_address = "test" 16 | self.assertEqual(self.client.data, {'query' : 'test'}) 17 | -------------------------------------------------------------------------------- /tests/test_url_builder.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from .common import CommonTestCase 3 | from dadata import LimitExceed, Errors 4 | 5 | 6 | class UrlBuildTest(CommonTestCase): 7 | """ 8 | Проверяем создание урла для запроса 9 | """ 10 | def test_address_url(self): 11 | url = self.client.address.url 12 | correct_url = self.client.url + '/clean/address' 13 | self.assertEqual(url, correct_url) 14 | 15 | def test_request_no_key(self): 16 | result = self.client.address.request() 17 | self.assertEqual(result, Errors.CLIENT_NO_KEY) 18 | 19 | #def test_request_no_secret(self): 20 | #result = self.client_with_key.address.request() 21 | #self.assertEqual(result, Errors.CLIENT_NO_SECRET) 22 | 23 | def test_request_no_data(self): 24 | result = self.client_with_key_secret.address.request() 25 | self.assertEqual(result, Errors.CLIENT_NO_DATA) 26 | 27 | 28 | class DataSetTest(CommonTestCase): 29 | """ 30 | Проверяем параметры и их лимиты 31 | """ 32 | def test_address_one_empty(self): 33 | self.assertEqual(self.client.address.one, None) 34 | 35 | def test_address_one_set(self): 36 | self.client.address = "Berkley Street 10" 37 | self.assertEqual(self.client.address.one, "Berkley Street 10") 38 | 39 | def test_address_many_set(self): 40 | self.client.address = ["Berkley Street 10", "Another Nice Street"] 41 | self.assertEqual(self.client.address.many, self.client.data) 42 | self.assertEqual(self.client.address.many, ["Berkley Street 10", "Another Nice Street"]) 43 | self.assertEqual(self.client.address.one, "Berkley Street 10") 44 | 45 | def test_address_many_set_over_limit(self): 46 | try: 47 | self.client.address.many = ["Berkley Street 10", "Another Nice Street", "10", "20"] 48 | except LimitExceed as e: 49 | self.assertTrue(e) 50 | self.assertFalse(self.client.address.many) 51 | --------------------------------------------------------------------------------