PyFunceble-dev 4.2.7__py3-none-any.whl → 4.2.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PyFunceble/checker/availability/base.py +8 -8
- PyFunceble/checker/availability/domain.py +0 -1
- PyFunceble/checker/availability/extras/base.py +1 -2
- PyFunceble/checker/availability/extras/rules.py +1 -1
- PyFunceble/checker/availability/ip.py +0 -1
- PyFunceble/checker/availability/url.py +0 -1
- PyFunceble/checker/reputation/base.py +0 -1
- PyFunceble/checker/reputation/domain.py +0 -1
- PyFunceble/checker/reputation/ip.py +0 -1
- PyFunceble/checker/reputation/url.py +0 -1
- PyFunceble/checker/syntax/second_lvl_domain.py +6 -2
- PyFunceble/checker/syntax/status.py +1 -0
- PyFunceble/checker/syntax/subdomain.py +3 -1
- PyFunceble/checker/syntax/url.py +0 -1
- PyFunceble/cli/credential_loader.py +3 -3
- PyFunceble/cli/entry_points/pyfunceble/cli.py +72 -6
- PyFunceble/cli/file_preloader.py +3 -3
- PyFunceble/cli/migrators/base.py +0 -1
- PyFunceble/cli/processes/workers/base.py +15 -6
- PyFunceble/cli/processes/workers/producer.py +5 -0
- PyFunceble/cli/scripts/production.py +3 -4
- PyFunceble/cli/storage.py +5 -3
- PyFunceble/cli/system/launcher.py +47 -1
- PyFunceble/cli/utils/testing.py +1 -3
- PyFunceble/config/loader.py +10 -0
- PyFunceble/data/alembic/mysql/versions/35c79626ecb9_fix_some_columns.py +1 -0
- PyFunceble/data/alembic/mysql/versions/3a4c55a9320d_add_continue_table.py +1 -0
- PyFunceble/data/alembic/mysql/versions/3d6f4a33cdb2_add_inactive_table.py +1 -0
- PyFunceble/data/alembic/mysql/versions/45713fea8097_deletion_uneeded_columns_from_whois_.py +1 -0
- PyFunceble/data/alembic/mysql/versions/459a0d7b8f09_add_idna_subject_column_into_whois.py +1 -0
- PyFunceble/data/alembic/mysql/versions/6f4729deaf03_delete_inactive_source_column.py +1 -0
- PyFunceble/data/alembic/mysql/versions/7bcf7fa64ba1_rename_created_to_created_at_and.py +1 -0
- PyFunceble/data/alembic/mysql/versions/83ada95132bf_delete_the_file_table.py +1 -0
- PyFunceble/data/alembic/mysql/versions/912bbcb77a6c_add_registrar_column.py +1 -0
- PyFunceble/data/alembic/mysql/versions/95dc17ddd729_introduction_of_the_session_id_column.py +1 -0
- PyFunceble/data/alembic/mysql/versions/ade87195b0a0_base.py +1 -0
- PyFunceble/data/alembic/mysql/versions/bef7bcaac3f2_make_id_a_bigint.py +1 -0
- PyFunceble/data/alembic/mysql/versions/d8893cd406db_allow_whois_record_to_be_empty_null.py +1 -0
- PyFunceble/data/alembic/mysql/versions/e04e8301d1a2_deletion_of_the_mined_table.py +1 -0
- PyFunceble/data/alembic/postgresql/versions/a32ac5d66eee_initial_version.py +1 -0
- PyFunceble/data/infrastructure/.PyFunceble_production.yaml +3 -0
- PyFunceble/query/collection.py +207 -11
- PyFunceble/query/requests/adapter/https.py +6 -6
- PyFunceble/query/whois/converter/digit2digits.py +1 -0
- PyFunceble/storage.py +4 -2
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/METADATA +42 -42
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/RECORD +51 -51
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/WHEEL +1 -1
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/LICENSE +0 -0
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/entry_points.txt +0 -0
- {PyFunceble_dev-4.2.7.dist-info → PyFunceble_dev-4.2.10.dist-info}/top_level.txt +0 -0
PyFunceble/query/collection.py
CHANGED
@@ -51,7 +51,7 @@ License:
|
|
51
51
|
"""
|
52
52
|
|
53
53
|
import json
|
54
|
-
from typing import List, Optional, Union
|
54
|
+
from typing import Generator, List, Optional, Union
|
55
55
|
|
56
56
|
import requests
|
57
57
|
import requests.exceptions
|
@@ -88,6 +88,7 @@ class CollectionQueryTool:
|
|
88
88
|
|
89
89
|
STD_URL_BASE: str = "http://localhost:8001"
|
90
90
|
STD_PREFERRED_STATUS_ORIGIN: str = "frequent"
|
91
|
+
STD_TIMEOUT: float = 5.0
|
91
92
|
|
92
93
|
_token: Optional[str] = None
|
93
94
|
"""
|
@@ -109,6 +110,11 @@ class CollectionQueryTool:
|
|
109
110
|
Whether we are working with the modern or legacy API.
|
110
111
|
"""
|
111
112
|
|
113
|
+
_timeout: float = 5.0
|
114
|
+
"""
|
115
|
+
The timeout to use while communicating with the API.
|
116
|
+
"""
|
117
|
+
|
112
118
|
session: Optional[requests.Session] = None
|
113
119
|
|
114
120
|
def __init__(
|
@@ -117,6 +123,7 @@ class CollectionQueryTool:
|
|
117
123
|
token: Optional[str] = None,
|
118
124
|
url_base: Optional[str] = None,
|
119
125
|
preferred_status_origin: Optional[str] = None,
|
126
|
+
timeout: Optional[float] = None,
|
120
127
|
) -> None:
|
121
128
|
if token is not None:
|
122
129
|
self.token = token
|
@@ -135,6 +142,11 @@ class CollectionQueryTool:
|
|
135
142
|
else:
|
136
143
|
self.guess_and_set_preferred_status_origin()
|
137
144
|
|
145
|
+
if timeout is not None:
|
146
|
+
self.timeout = timeout
|
147
|
+
else:
|
148
|
+
self.guess_and_set_timeout()
|
149
|
+
|
138
150
|
self.session = requests.Session()
|
139
151
|
self.session.headers.update(
|
140
152
|
{
|
@@ -283,6 +295,43 @@ class CollectionQueryTool:
|
|
283
295
|
|
284
296
|
return self
|
285
297
|
|
298
|
+
@property
|
299
|
+
def timeout(self) -> float:
|
300
|
+
"""
|
301
|
+
Provides the value of the :code:`_timeout` attribute.
|
302
|
+
"""
|
303
|
+
|
304
|
+
return self._timeout
|
305
|
+
|
306
|
+
@timeout.setter
|
307
|
+
def timeout(self, value: float) -> None:
|
308
|
+
"""
|
309
|
+
Sets the value of the :code:`_timeout` attribute.
|
310
|
+
|
311
|
+
:param value:
|
312
|
+
The value to set.
|
313
|
+
|
314
|
+
:raise TypeError:
|
315
|
+
When the given :code:`value` is not a :py:class:`float`.
|
316
|
+
"""
|
317
|
+
|
318
|
+
if not isinstance(value, (int, float)):
|
319
|
+
raise TypeError(f"<value> should be {float}, {type(value)} given.")
|
320
|
+
|
321
|
+
self._timeout = value
|
322
|
+
|
323
|
+
def set_timeout(self, value: float) -> "CollectionQueryTool":
|
324
|
+
"""
|
325
|
+
Sets the value of the :code:`_timeout` attribute.
|
326
|
+
|
327
|
+
:param value:
|
328
|
+
The value to set.
|
329
|
+
"""
|
330
|
+
|
331
|
+
self.timeout = value
|
332
|
+
|
333
|
+
return self
|
334
|
+
|
286
335
|
def guess_and_set_url_base(self) -> "CollectionQueryTool":
|
287
336
|
"""
|
288
337
|
Try to guess the URL base to work with.
|
@@ -307,16 +356,22 @@ class CollectionQueryTool:
|
|
307
356
|
Try to guess if we are working with a legacy version.
|
308
357
|
"""
|
309
358
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
359
|
+
if self.token:
|
360
|
+
try:
|
361
|
+
response = self.session.get(
|
362
|
+
f"{self.url_base}/v1/stats/subject",
|
363
|
+
timeout=self.timeout,
|
364
|
+
)
|
314
365
|
|
315
|
-
|
366
|
+
response.raise_for_status()
|
316
367
|
|
368
|
+
self.is_modern_api = False
|
369
|
+
except (requests.RequestException, json.decoder.JSONDecodeError):
|
370
|
+
self.is_modern_api = True
|
371
|
+
else:
|
317
372
|
self.is_modern_api = False
|
318
|
-
|
319
|
-
|
373
|
+
|
374
|
+
return self
|
320
375
|
|
321
376
|
@property
|
322
377
|
def preferred_status_origin(self) -> Optional[str]:
|
@@ -380,7 +435,19 @@ class CollectionQueryTool:
|
|
380
435
|
|
381
436
|
return self
|
382
437
|
|
383
|
-
def
|
438
|
+
def guess_and_set_timeout(self) -> "CollectionQueryTool":
|
439
|
+
"""
|
440
|
+
Try to guess the timeout to use.
|
441
|
+
"""
|
442
|
+
|
443
|
+
if PyFunceble.facility.ConfigLoader.is_already_loaded():
|
444
|
+
self.timeout = PyFunceble.storage.CONFIGURATION.lookup.timeout
|
445
|
+
else:
|
446
|
+
self.timeout = self.STD_TIMEOUT
|
447
|
+
|
448
|
+
return self
|
449
|
+
|
450
|
+
def ensure_modern_api(func): # pylint: disable=no-self-argument
|
384
451
|
"""
|
385
452
|
Ensures that the :code:`is_modern_api` attribute is set before running
|
386
453
|
the decorated method.
|
@@ -394,7 +461,7 @@ class CollectionQueryTool:
|
|
394
461
|
|
395
462
|
return wrapper
|
396
463
|
|
397
|
-
@
|
464
|
+
@ensure_modern_api
|
398
465
|
def pull(self, subject: str) -> Optional[dict]:
|
399
466
|
"""
|
400
467
|
Pulls all data related to the subject or :py:class:`None`
|
@@ -426,6 +493,7 @@ class CollectionQueryTool:
|
|
426
493
|
response = self.session.post(
|
427
494
|
url,
|
428
495
|
json={"subject": subject},
|
496
|
+
timeout=self.timeout,
|
429
497
|
)
|
430
498
|
|
431
499
|
response_json = response.json()
|
@@ -452,7 +520,113 @@ class CollectionQueryTool:
|
|
452
520
|
|
453
521
|
return None
|
454
522
|
|
455
|
-
@
|
523
|
+
@ensure_modern_api
|
524
|
+
def pull_contract(self, amount: int = 1) -> Generator[dict, None, None]:
|
525
|
+
"""
|
526
|
+
Pulls the next amount of contracts.
|
527
|
+
|
528
|
+
:param int amount:
|
529
|
+
The amount of data to pull.
|
530
|
+
|
531
|
+
:return:
|
532
|
+
The response of the query.
|
533
|
+
"""
|
534
|
+
|
535
|
+
PyFunceble.facility.Logger.info("Starting to pull next contract")
|
536
|
+
|
537
|
+
url = f"{self.url_base}/v1/contracts/next"
|
538
|
+
params = {
|
539
|
+
"limit": amount,
|
540
|
+
"shuffle": True,
|
541
|
+
}
|
542
|
+
|
543
|
+
try:
|
544
|
+
response = self.session.get(
|
545
|
+
url,
|
546
|
+
params=params,
|
547
|
+
timeout=self.timeout,
|
548
|
+
)
|
549
|
+
|
550
|
+
response_json = response.json()
|
551
|
+
|
552
|
+
if response.status_code == 200:
|
553
|
+
PyFunceble.facility.Logger.debug(
|
554
|
+
"Successfully pulled next %r contracts. Response: %r", response_json
|
555
|
+
)
|
556
|
+
|
557
|
+
PyFunceble.facility.Logger.info("Finished to pull next contract")
|
558
|
+
|
559
|
+
yield response_json
|
560
|
+
except (requests.RequestException, json.decoder.JSONDecodeError):
|
561
|
+
response_json = [{"subject": {}}]
|
562
|
+
|
563
|
+
PyFunceble.facility.Logger.debug(
|
564
|
+
"Failed to pull next contract. Response: %r", response_json
|
565
|
+
)
|
566
|
+
PyFunceble.facility.Logger.info("Finished to pull next contracts")
|
567
|
+
|
568
|
+
yield response_json
|
569
|
+
|
570
|
+
@ensure_modern_api
|
571
|
+
def deliver_contract(self, contract: dict, contract_data: dict) -> Optional[dict]:
|
572
|
+
"""
|
573
|
+
Delivers the given contract data.
|
574
|
+
|
575
|
+
:param contract:
|
576
|
+
The contract to deliver.
|
577
|
+
:param contract_data:
|
578
|
+
The data to deliver.
|
579
|
+
|
580
|
+
:return:
|
581
|
+
The response of the query.
|
582
|
+
"""
|
583
|
+
|
584
|
+
PyFunceble.facility.Logger.info(
|
585
|
+
"Starting to deliver contract data: %r", contract
|
586
|
+
)
|
587
|
+
|
588
|
+
contract_id = contract["id"]
|
589
|
+
contract_data = (
|
590
|
+
contract_data.to_json()
|
591
|
+
if not isinstance(contract_data, dict)
|
592
|
+
else contract_data
|
593
|
+
)
|
594
|
+
url = f"{self.url_base}/v1/contracts/{contract_id}/delivery"
|
595
|
+
|
596
|
+
try:
|
597
|
+
response = self.session.post(
|
598
|
+
url,
|
599
|
+
data=contract_data.encode("utf-8"),
|
600
|
+
timeout=self.timeout,
|
601
|
+
)
|
602
|
+
|
603
|
+
response_json = response.json()
|
604
|
+
|
605
|
+
if response.status_code == 200:
|
606
|
+
PyFunceble.facility.Logger.debug(
|
607
|
+
"Successfully delivered contract: %r. Response: %r",
|
608
|
+
contract_data,
|
609
|
+
response_json,
|
610
|
+
)
|
611
|
+
|
612
|
+
PyFunceble.facility.Logger.info(
|
613
|
+
"Finished to deliver contract: %r", contract_data
|
614
|
+
)
|
615
|
+
|
616
|
+
return response_json
|
617
|
+
except (requests.RequestException, json.decoder.JSONDecodeError):
|
618
|
+
response_json = {}
|
619
|
+
|
620
|
+
PyFunceble.facility.Logger.debug(
|
621
|
+
"Failed to deliver contract: %r. Response: %r", contract_data, response_json
|
622
|
+
)
|
623
|
+
PyFunceble.facility.Logger.info(
|
624
|
+
"Finished to deliver contract: %r", contract_data
|
625
|
+
)
|
626
|
+
|
627
|
+
return None
|
628
|
+
|
629
|
+
@ensure_modern_api
|
456
630
|
def push(
|
457
631
|
self,
|
458
632
|
checker_status: Union[
|
@@ -574,11 +748,26 @@ class CollectionQueryTool:
|
|
574
748
|
response = self.session.post(
|
575
749
|
url,
|
576
750
|
json=data,
|
751
|
+
timeout=self.timeout,
|
752
|
+
)
|
753
|
+
elif isinstance(
|
754
|
+
data,
|
755
|
+
(
|
756
|
+
AvailabilityCheckerStatus,
|
757
|
+
SyntaxCheckerStatus,
|
758
|
+
ReputationCheckerStatus,
|
759
|
+
),
|
760
|
+
):
|
761
|
+
response = self.session.post(
|
762
|
+
url,
|
763
|
+
json=data.to_dict(),
|
764
|
+
timeout=self.timeout,
|
577
765
|
)
|
578
766
|
else:
|
579
767
|
response = self.session.post(
|
580
768
|
url,
|
581
769
|
data=data,
|
770
|
+
timeout=self.timeout,
|
582
771
|
)
|
583
772
|
|
584
773
|
response_json = response.json()
|
@@ -622,6 +811,12 @@ class CollectionQueryTool:
|
|
622
811
|
if not self.token:
|
623
812
|
return None
|
624
813
|
|
814
|
+
if isinstance(
|
815
|
+
data,
|
816
|
+
(AvailabilityCheckerStatus, SyntaxCheckerStatus, ReputationCheckerStatus),
|
817
|
+
):
|
818
|
+
data = data.to_dict()
|
819
|
+
|
625
820
|
if not isinstance(data, dict): # pragma: no cover ## Should never happen
|
626
821
|
raise TypeError(f"<data> should be {dict}, {type(data)} given.")
|
627
822
|
|
@@ -633,6 +828,7 @@ class CollectionQueryTool:
|
|
633
828
|
response = self.session.post(
|
634
829
|
url,
|
635
830
|
json=data,
|
831
|
+
timeout=self.timeout,
|
636
832
|
)
|
637
833
|
|
638
834
|
response_json = response.json()
|
@@ -113,12 +113,12 @@ class RequestHTTPSAdapter(RequestAdapterBase):
|
|
113
113
|
)
|
114
114
|
|
115
115
|
if parsed_url.scheme == "https":
|
116
|
-
self.poolmanager.connection_pool_kw[
|
117
|
-
|
118
|
-
|
119
|
-
self.poolmanager.connection_pool_kw[
|
120
|
-
|
121
|
-
|
116
|
+
self.poolmanager.connection_pool_kw["server_hostname"] = (
|
117
|
+
parsed_url.hostname
|
118
|
+
)
|
119
|
+
self.poolmanager.connection_pool_kw["assert_hostname"] = (
|
120
|
+
parsed_url.hostname
|
121
|
+
)
|
122
122
|
|
123
123
|
# Ensure that the Hosts header is present. Otherwise, connection might
|
124
124
|
# not work.
|
PyFunceble/storage.py
CHANGED
@@ -61,7 +61,7 @@ from dotenv import load_dotenv
|
|
61
61
|
from PyFunceble.storage_facility import get_config_directory
|
62
62
|
|
63
63
|
PROJECT_NAME: str = "PyFunceble"
|
64
|
-
PROJECT_VERSION: str = "4.2.
|
64
|
+
PROJECT_VERSION: str = "4.2.10.dev (Blue Duckling: Ixora)"
|
65
65
|
|
66
66
|
DISTRIBUTED_CONFIGURATION_FILENAME: str = ".PyFunceble_production.yaml"
|
67
67
|
DISTRIBUTED_DIR_STRUCTURE_FILENAME: str = "dir_structure_production.json"
|
@@ -79,7 +79,9 @@ IPV4_REPUTATION_FILENAME: str = "ipv4_reputation.data"
|
|
79
79
|
IANA_DUMP_LINK: str = (
|
80
80
|
"https://raw.githubusercontent.com/PyFunceble/iana/master/iana-domains-db.json"
|
81
81
|
)
|
82
|
-
PUBLIC_SUFFIX_DUMP_LINK: str =
|
82
|
+
PUBLIC_SUFFIX_DUMP_LINK: str = (
|
83
|
+
"https://raw.githubusercontent.com/PyFunceble/public-suffix/master/public-suffix.json"
|
84
|
+
)
|
83
85
|
USER_AGENT_DUMP_LINK: str = (
|
84
86
|
"https://raw.githubusercontent.com/PyFunceble/user_agents/master/user_agents.json"
|
85
87
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: PyFunceble-dev
|
3
|
-
Version: 4.2.
|
3
|
+
Version: 4.2.10
|
4
4
|
Summary: The tool to check the availability or syntax of domain, IP or URL.
|
5
5
|
Home-page: https://github.com/funilrys/PyFunceble
|
6
6
|
Author: funilrys
|
@@ -21,74 +21,74 @@ Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: License :: OSI Approved
|
22
22
|
Requires-Python: >=3.8, <4
|
23
23
|
License-File: LICENSE
|
24
|
-
Requires-Dist:
|
24
|
+
Requires-Dist: dnspython[doh] ~=2.6.0
|
25
|
+
Requires-Dist: shtab
|
25
26
|
Requires-Dist: domain2idna ~=1.12.0
|
26
|
-
Requires-Dist:
|
27
|
-
Requires-Dist: dnspython[doh] ~=2.0.0
|
27
|
+
Requires-Dist: inflection
|
28
28
|
Requires-Dist: PyMySQL
|
29
|
-
Requires-Dist:
|
29
|
+
Requires-Dist: SQLAlchemy ~=2.0
|
30
|
+
Requires-Dist: python-dotenv
|
31
|
+
Requires-Dist: colorama
|
32
|
+
Requires-Dist: alembic
|
30
33
|
Requires-Dist: requests[socks] <3
|
31
|
-
Requires-Dist:
|
34
|
+
Requires-Dist: setuptools >=65.5.1
|
32
35
|
Requires-Dist: packaging
|
33
36
|
Requires-Dist: PyYAML
|
34
|
-
Requires-Dist:
|
35
|
-
Requires-Dist:
|
36
|
-
Requires-Dist: setuptools >=65.5.1
|
37
|
-
Requires-Dist: SQLAlchemy ~=2.0
|
38
|
-
Requires-Dist: colorama
|
37
|
+
Requires-Dist: python-box[all] ~=6.0.0
|
38
|
+
Requires-Dist: cryptography ~=42.0
|
39
39
|
Provides-Extra: dev
|
40
|
-
Requires-Dist: flake8 ; extra == 'dev'
|
41
40
|
Requires-Dist: isort ; extra == 'dev'
|
42
|
-
Requires-Dist: pylint ; extra == 'dev'
|
43
41
|
Requires-Dist: black ; extra == 'dev'
|
42
|
+
Requires-Dist: pylint ; extra == 'dev'
|
43
|
+
Requires-Dist: flake8 ; extra == 'dev'
|
44
44
|
Provides-Extra: docs
|
45
45
|
Requires-Dist: alabaster <0.8,>=0.7 ; extra == 'docs'
|
46
|
-
Requires-Dist: sphinx >=3.4.3 ; extra == 'docs'
|
47
|
-
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
48
46
|
Requires-Dist: Pygments >=2.0 ; extra == 'docs'
|
47
|
+
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
48
|
+
Requires-Dist: sphinx >=3.4.3 ; extra == 'docs'
|
49
49
|
Provides-Extra: full
|
50
|
-
Requires-Dist: alembic ; extra == 'full'
|
51
50
|
Requires-Dist: PyMySQL ; extra == 'full'
|
52
|
-
Requires-Dist: sphinx-rtd-theme ; extra == 'full'
|
53
51
|
Requires-Dist: isort ; extra == 'full'
|
54
|
-
Requires-Dist:
|
52
|
+
Requires-Dist: Pygments >=2.0 ; extra == 'full'
|
55
53
|
Requires-Dist: flake8 ; extra == 'full'
|
56
|
-
Requires-Dist: tox ; extra == 'full'
|
57
|
-
Requires-Dist: dnspython[doh] ~=2.0.0 ; extra == 'full'
|
58
|
-
Requires-Dist: python-box[all] ~=6.0.0 ; extra == 'full'
|
59
|
-
Requires-Dist: cryptography >=3.3.2 ; extra == 'full'
|
60
|
-
Requires-Dist: packaging ; extra == 'full'
|
61
|
-
Requires-Dist: coverage ; extra == 'full'
|
62
|
-
Requires-Dist: setuptools >=65.5.1 ; extra == 'full'
|
63
54
|
Requires-Dist: alabaster <0.8,>=0.7 ; extra == 'full'
|
64
|
-
Requires-Dist:
|
65
|
-
Requires-Dist: pylint ; extra == 'full'
|
55
|
+
Requires-Dist: dnspython[doh] ~=2.6.0 ; extra == 'full'
|
66
56
|
Requires-Dist: domain2idna ~=1.12.0 ; extra == 'full'
|
67
57
|
Requires-Dist: python-dotenv ; extra == 'full'
|
58
|
+
Requires-Dist: colorama ; extra == 'full'
|
59
|
+
Requires-Dist: packaging ; extra == 'full'
|
60
|
+
Requires-Dist: pylint ; extra == 'full'
|
61
|
+
Requires-Dist: tox ; extra == 'full'
|
62
|
+
Requires-Dist: black ; extra == 'full'
|
63
|
+
Requires-Dist: coverage ; extra == 'full'
|
68
64
|
Requires-Dist: requests[socks] <3 ; extra == 'full'
|
69
|
-
Requires-Dist:
|
65
|
+
Requires-Dist: PyYAML ; extra == 'full'
|
66
|
+
Requires-Dist: python-box[all] ~=6.0.0 ; extra == 'full'
|
67
|
+
Requires-Dist: shtab ; extra == 'full'
|
70
68
|
Requires-Dist: sphinx >=3.4.3 ; extra == 'full'
|
71
|
-
Requires-Dist:
|
69
|
+
Requires-Dist: SQLAlchemy ~=2.0 ; extra == 'full'
|
72
70
|
Requires-Dist: inflection ; extra == 'full'
|
73
|
-
Requires-Dist:
|
74
|
-
Requires-Dist:
|
71
|
+
Requires-Dist: alembic ; extra == 'full'
|
72
|
+
Requires-Dist: setuptools >=65.5.1 ; extra == 'full'
|
73
|
+
Requires-Dist: sphinx-rtd-theme ; extra == 'full'
|
74
|
+
Requires-Dist: cryptography ~=42.0 ; extra == 'full'
|
75
75
|
Provides-Extra: psql
|
76
|
-
Requires-Dist:
|
76
|
+
Requires-Dist: dnspython[doh] ~=2.6.0 ; extra == 'psql'
|
77
|
+
Requires-Dist: shtab ; extra == 'psql'
|
77
78
|
Requires-Dist: domain2idna ~=1.12.0 ; extra == 'psql'
|
78
|
-
Requires-Dist:
|
79
|
-
Requires-Dist: psycopg2 ; extra == 'psql'
|
80
|
-
Requires-Dist: dnspython[doh] ~=2.0.0 ; extra == 'psql'
|
79
|
+
Requires-Dist: inflection ; extra == 'psql'
|
81
80
|
Requires-Dist: PyMySQL ; extra == 'psql'
|
82
|
-
Requires-Dist:
|
81
|
+
Requires-Dist: SQLAlchemy ~=2.0 ; extra == 'psql'
|
82
|
+
Requires-Dist: python-dotenv ; extra == 'psql'
|
83
|
+
Requires-Dist: colorama ; extra == 'psql'
|
84
|
+
Requires-Dist: alembic ; extra == 'psql'
|
83
85
|
Requires-Dist: requests[socks] <3 ; extra == 'psql'
|
84
|
-
Requires-Dist:
|
86
|
+
Requires-Dist: setuptools >=65.5.1 ; extra == 'psql'
|
87
|
+
Requires-Dist: psycopg2 ; extra == 'psql'
|
85
88
|
Requires-Dist: packaging ; extra == 'psql'
|
86
89
|
Requires-Dist: PyYAML ; extra == 'psql'
|
87
|
-
Requires-Dist:
|
88
|
-
Requires-Dist:
|
89
|
-
Requires-Dist: setuptools >=65.5.1 ; extra == 'psql'
|
90
|
-
Requires-Dist: SQLAlchemy ~=2.0 ; extra == 'psql'
|
91
|
-
Requires-Dist: colorama ; extra == 'psql'
|
90
|
+
Requires-Dist: python-box[all] ~=6.0.0 ; extra == 'psql'
|
91
|
+
Requires-Dist: cryptography ~=42.0 ; extra == 'psql'
|
92
92
|
Provides-Extra: test
|
93
93
|
Requires-Dist: tox ; extra == 'test'
|
94
94
|
Requires-Dist: coverage ; extra == 'test'
|