castor-extractor 0.20.7__py3-none-any.whl → 0.21.1__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.
Potentially problematic release.
This version of castor-extractor might be problematic. Click here for more details.
- CHANGELOG.md +12 -0
- castor_extractor/commands/__init__.py +3 -0
- castor_extractor/commands/extract_confluence.py +19 -0
- castor_extractor/knowledge/confluence/__init__.py +3 -0
- castor_extractor/knowledge/confluence/assets.py +8 -0
- castor_extractor/knowledge/confluence/client/__init__.py +2 -0
- castor_extractor/knowledge/confluence/client/client.py +60 -0
- castor_extractor/knowledge/confluence/client/credentials.py +18 -0
- castor_extractor/knowledge/confluence/client/endpoints.py +25 -0
- castor_extractor/knowledge/confluence/client/pagination.py +32 -0
- castor_extractor/knowledge/confluence/extract.py +54 -0
- castor_extractor/utils/deprecate.py +3 -3
- {castor_extractor-0.20.7.dist-info → castor_extractor-0.21.1.dist-info}/METADATA +14 -2
- {castor_extractor-0.20.7.dist-info → castor_extractor-0.21.1.dist-info}/RECORD +17 -8
- {castor_extractor-0.20.7.dist-info → castor_extractor-0.21.1.dist-info}/WHEEL +1 -1
- {castor_extractor-0.20.7.dist-info → castor_extractor-0.21.1.dist-info}/entry_points.txt +1 -0
- {castor_extractor-0.20.7.dist-info → castor_extractor-0.21.1.dist-info}/LICENCE +0 -0
CHANGELOG.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
# Changelog
|
|
3
3
|
|
|
4
|
+
## 0.21.1 - 2024-10-23
|
|
5
|
+
|
|
6
|
+
* Warning message to deprecate python < 3.9
|
|
7
|
+
|
|
8
|
+
## 0.21.0 - 2024-10-23
|
|
9
|
+
|
|
10
|
+
* Confluence: Added Confluence extractor
|
|
11
|
+
|
|
12
|
+
## 0.20.8 - 2024-10-19
|
|
13
|
+
|
|
14
|
+
* bump dependencies (minor and patches)
|
|
15
|
+
|
|
4
16
|
## 0.20.7 - 2024-10-18
|
|
5
17
|
|
|
6
18
|
* Metabase: fix `require_ssl` type in credentials
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from argparse import ArgumentParser
|
|
3
|
+
|
|
4
|
+
from castor_extractor.knowledge import confluence # type: ignore
|
|
5
|
+
from castor_extractor.utils import parse_filled_arguments # type: ignore
|
|
6
|
+
|
|
7
|
+
logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
parser = ArgumentParser()
|
|
12
|
+
|
|
13
|
+
parser.add_argument("-a", "--account_id", help="Confluence account id")
|
|
14
|
+
parser.add_argument("-b", "--base_url", help="Confluence account base url")
|
|
15
|
+
parser.add_argument("-o", "--output", help="Directory to write to")
|
|
16
|
+
parser.add_argument("-p", "--password", help="Confluence password")
|
|
17
|
+
parser.add_argument("-u", "--username", help="Confluence username")
|
|
18
|
+
|
|
19
|
+
confluence.extract_all(**parse_filled_arguments(parser))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from functools import partial
|
|
2
|
+
from http import HTTPStatus
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from ....utils import (
|
|
6
|
+
APIClient,
|
|
7
|
+
BasicAuth,
|
|
8
|
+
RequestSafeMode,
|
|
9
|
+
fetch_all_pages,
|
|
10
|
+
)
|
|
11
|
+
from .credentials import ConfluenceCredentials
|
|
12
|
+
from .endpoints import ConfluenceEndpointFactory
|
|
13
|
+
from .pagination import ConfluencePagination
|
|
14
|
+
|
|
15
|
+
_HEADERS = {
|
|
16
|
+
"Accept": "application/json",
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
_MAX_ERROR_IGNORED_COUNT = 10
|
|
21
|
+
_IGNORED_ERROR_CODES = (HTTPStatus.BAD_GATEWAY,)
|
|
22
|
+
_SAFE_MODE = RequestSafeMode(
|
|
23
|
+
max_errors=_MAX_ERROR_IGNORED_COUNT,
|
|
24
|
+
status_codes=_IGNORED_ERROR_CODES,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConfluenceClient(APIClient):
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
credentials: ConfluenceCredentials,
|
|
32
|
+
safe_mode: Optional[RequestSafeMode] = None,
|
|
33
|
+
):
|
|
34
|
+
self.account_id = credentials.account_id
|
|
35
|
+
auth = BasicAuth(
|
|
36
|
+
username=credentials.username, password=credentials.password
|
|
37
|
+
)
|
|
38
|
+
super().__init__(
|
|
39
|
+
auth=auth,
|
|
40
|
+
host=credentials.base_url,
|
|
41
|
+
headers=_HEADERS,
|
|
42
|
+
safe_mode=safe_mode or _SAFE_MODE,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def pages(self):
|
|
46
|
+
request = partial(
|
|
47
|
+
self._get,
|
|
48
|
+
endpoint=ConfluenceEndpointFactory.pages(),
|
|
49
|
+
params={"body-format": "atlas_doc_format"},
|
|
50
|
+
)
|
|
51
|
+
yield from fetch_all_pages(request, ConfluencePagination)
|
|
52
|
+
|
|
53
|
+
def users(self):
|
|
54
|
+
request_body = {"accountIds": [self.account_id]}
|
|
55
|
+
request = partial(
|
|
56
|
+
self._post,
|
|
57
|
+
endpoint=ConfluenceEndpointFactory.users(),
|
|
58
|
+
data=request_body,
|
|
59
|
+
)
|
|
60
|
+
yield from fetch_all_pages(request, ConfluencePagination)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
2
|
+
|
|
3
|
+
CASTOR_ENV_PREFIX = "CASTOR_CONFLUENCE_"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConfluenceCredentials(BaseSettings):
|
|
7
|
+
"""Class to handle Confluence rest API permissions"""
|
|
8
|
+
|
|
9
|
+
model_config = SettingsConfigDict(
|
|
10
|
+
env_prefix=CASTOR_ENV_PREFIX,
|
|
11
|
+
extra="ignore",
|
|
12
|
+
populate_by_name=True,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
account_id: str
|
|
16
|
+
base_url: str
|
|
17
|
+
password: str
|
|
18
|
+
username: str
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class ConfluenceEndpointFactory:
|
|
2
|
+
"""
|
|
3
|
+
Confluence rest api v2 endpoint factory.
|
|
4
|
+
https://developer.atlassian.com/cloud/confluence/rest/v2/intro/#about
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
API = "wiki/api/v2/"
|
|
8
|
+
PAGES = "pages"
|
|
9
|
+
USERS = "users-bulk"
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def pages(cls) -> str:
|
|
13
|
+
"""
|
|
14
|
+
Endpoint to fetch all pages.
|
|
15
|
+
More: https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-page/#api-pages-get
|
|
16
|
+
"""
|
|
17
|
+
return f"{cls.API}{cls.PAGES}"
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def users(cls) -> str:
|
|
21
|
+
"""
|
|
22
|
+
Endpoint to fetch all user.
|
|
23
|
+
More: https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-user/#api-users-bulk-post
|
|
24
|
+
"""
|
|
25
|
+
return f"{cls.API}{cls.USERS}"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
|
|
3
|
+
from pydantic import AliasPath, Field
|
|
4
|
+
|
|
5
|
+
from ....utils import (
|
|
6
|
+
FetchNextPageBy,
|
|
7
|
+
PaginationModel,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConfluencePagination(PaginationModel):
|
|
12
|
+
"""Class to handle paginated results for confluence"""
|
|
13
|
+
|
|
14
|
+
fetch_by: FetchNextPageBy = FetchNextPageBy.URL
|
|
15
|
+
|
|
16
|
+
results: list = Field(default_factory=list)
|
|
17
|
+
next_url: Optional[str] = Field(
|
|
18
|
+
validation_alias=AliasPath("_links", "next"),
|
|
19
|
+
default=None,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def is_last(self) -> bool:
|
|
23
|
+
"""Stopping condition for the pagination"""
|
|
24
|
+
return self.next_url is None
|
|
25
|
+
|
|
26
|
+
def next_page_payload(self) -> Union[str, None]:
|
|
27
|
+
"""Payload enabling to generate the request for the next page"""
|
|
28
|
+
return self.next_url
|
|
29
|
+
|
|
30
|
+
def page_results(self) -> list:
|
|
31
|
+
"""List of results of the current page"""
|
|
32
|
+
return self.results
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Iterable, Iterator, Tuple, Union
|
|
3
|
+
|
|
4
|
+
from ...utils import (
|
|
5
|
+
OUTPUT_DIR,
|
|
6
|
+
current_timestamp,
|
|
7
|
+
deep_serialize,
|
|
8
|
+
from_env,
|
|
9
|
+
get_output_filename,
|
|
10
|
+
write_json,
|
|
11
|
+
write_summary,
|
|
12
|
+
)
|
|
13
|
+
from .assets import ConfluenceAsset
|
|
14
|
+
from .client import ConfluenceClient, ConfluenceCredentials
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def iterate_all_data(
|
|
20
|
+
client: ConfluenceClient,
|
|
21
|
+
) -> Iterable[Tuple[ConfluenceAsset, Union[list, Iterator, dict]]]:
|
|
22
|
+
"""Iterate over the extracted data from Confluence"""
|
|
23
|
+
|
|
24
|
+
logger.info("Extracting USERS from API")
|
|
25
|
+
users = list(deep_serialize(client.users()))
|
|
26
|
+
yield ConfluenceAsset.USERS, users
|
|
27
|
+
logger.info(f"Extracted {len(users)} users from API")
|
|
28
|
+
|
|
29
|
+
logger.info("Extracting PAGES from API")
|
|
30
|
+
pages = list(deep_serialize(client.pages()))
|
|
31
|
+
yield ConfluenceAsset.PAGES, pages
|
|
32
|
+
logger.info(f"Extracted {len(pages)} pages from API")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def extract_all(**kwargs) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Extract data from Confluence API
|
|
38
|
+
Store the output files locally under the given output_directory
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
output_directory = kwargs.get("output") or from_env(OUTPUT_DIR)
|
|
42
|
+
|
|
43
|
+
credentials = ConfluenceCredentials(**kwargs)
|
|
44
|
+
client = ConfluenceClient(credentials=credentials)
|
|
45
|
+
|
|
46
|
+
ts = current_timestamp()
|
|
47
|
+
|
|
48
|
+
for key, data in iterate_all_data(client):
|
|
49
|
+
filename = get_output_filename(key.name.lower(), output_directory, ts)
|
|
50
|
+
write_json(filename, data)
|
|
51
|
+
|
|
52
|
+
es = current_timestamp()
|
|
53
|
+
|
|
54
|
+
write_summary(output_directory, ts, duration_second=es - ts)
|
|
@@ -4,7 +4,7 @@ import warnings
|
|
|
4
4
|
from typing import Tuple
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def deprecate_python(min_version_supported: Tuple[int]):
|
|
7
|
+
def deprecate_python(min_version_supported: Tuple[int, ...]):
|
|
8
8
|
"""raises a warning if python version < min_version_supported"""
|
|
9
9
|
|
|
10
10
|
python_version = (
|
|
@@ -22,5 +22,5 @@ def deprecate_python(min_version_supported: Tuple[int]):
|
|
|
22
22
|
if python_version < min_version_supported:
|
|
23
23
|
warnings.warn(message, DeprecationWarning)
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
# Since warnings are disabled by default, let's add a log as well
|
|
26
|
+
logging.warning(message)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: castor-extractor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.1
|
|
4
4
|
Summary: Extract your metadata assets.
|
|
5
5
|
Home-page: https://www.castordoc.com/
|
|
6
6
|
License: EULA
|
|
@@ -37,7 +37,7 @@ Requires-Dist: google-cloud-core (>=2.1.0,<3.0.0)
|
|
|
37
37
|
Requires-Dist: google-cloud-storage (>=2,<3)
|
|
38
38
|
Requires-Dist: google-resumable-media (>=2.0.3,<3.0.0)
|
|
39
39
|
Requires-Dist: googleapis-common-protos (>=1.53.0,<2.0.0)
|
|
40
|
-
Requires-Dist: looker-sdk (>=24.
|
|
40
|
+
Requires-Dist: looker-sdk (>=24.16.0,<24.17.0) ; extra == "looker" or extra == "all"
|
|
41
41
|
Requires-Dist: msal (>=1.20.0,<2.0.0) ; extra == "powerbi" or extra == "all"
|
|
42
42
|
Requires-Dist: numpy (<1.25) ; (python_version >= "3.8" and python_version < "3.9") and (extra == "bigquery" or extra == "databricks" or extra == "all")
|
|
43
43
|
Requires-Dist: numpy (<2) ; extra == "bigquery" or extra == "databricks" or extra == "all"
|
|
@@ -208,6 +208,18 @@ For any questions or bug report, contact us at [support@castordoc.com](mailto:su
|
|
|
208
208
|
|
|
209
209
|
# Changelog
|
|
210
210
|
|
|
211
|
+
## 0.21.1 - 2024-10-23
|
|
212
|
+
|
|
213
|
+
* Warning message to deprecate python < 3.9
|
|
214
|
+
|
|
215
|
+
## 0.21.0 - 2024-10-23
|
|
216
|
+
|
|
217
|
+
* Confluence: Added Confluence extractor
|
|
218
|
+
|
|
219
|
+
## 0.20.8 - 2024-10-19
|
|
220
|
+
|
|
221
|
+
* bump dependencies (minor and patches)
|
|
222
|
+
|
|
211
223
|
## 0.20.7 - 2024-10-18
|
|
212
224
|
|
|
213
225
|
* Metabase: fix `require_ssl` type in credentials
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
CHANGELOG.md,sha256=
|
|
1
|
+
CHANGELOG.md,sha256=U0folo6uva597R9IArkQzRau3UldJIdvq99aWOEWKkA,14355
|
|
2
2
|
Dockerfile,sha256=xQ05-CFfGShT3oUqaiumaldwA288dj9Yb_pxofQpufg,301
|
|
3
3
|
DockerfileUsage.md,sha256=2hkJQF-5JuuzfPZ7IOxgM6QgIQW7l-9oRMFVwyXC4gE,998
|
|
4
4
|
LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
5
5
|
README.md,sha256=uF6PXm9ocPITlKVSh9afTakHmpLx3TvawLf-CbMP3wM,3578
|
|
6
6
|
castor_extractor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
castor_extractor/commands/__init__.py,sha256=
|
|
7
|
+
castor_extractor/commands/__init__.py,sha256=qnCeLzbb8dlNJYr-P1ZMqHmNoXyaoojC8MkDUEZkfSk,116
|
|
8
8
|
castor_extractor/commands/extract_bigquery.py,sha256=dU4OiYO1V0n32orvZnMh1_xtFKF_VxHNXcVsH3otY-g,1269
|
|
9
|
+
castor_extractor/commands/extract_confluence.py,sha256=o4vjN7nxN2MQWyLgdgjbaO9Rd53f2icYst5tv_evwT4,750
|
|
9
10
|
castor_extractor/commands/extract_databricks.py,sha256=SVKyoa-BBUQAM6HRHf1Wdg9-tpICic2yyvXQwHcNBhA,1264
|
|
10
11
|
castor_extractor/commands/extract_domo.py,sha256=jvAawUsUTHrwCn_koK6StmQr4n_b5GyvJi6uu6WS0SM,1061
|
|
11
12
|
castor_extractor/commands/extract_looker.py,sha256=cySLiolLCgrREJ9d0kMrJ7P8K3efHTBTzShalWVfI3A,1214
|
|
@@ -39,6 +40,14 @@ castor_extractor/file_checker/file_test_users_valid.csv,sha256=Ek3q7DjUS0neOu1LQ
|
|
|
39
40
|
castor_extractor/file_checker/templates/__init__.py,sha256=StVLm4ZGyGVmPzarxEaDR_k08T3nUnyiv8N99sAz6AQ,60
|
|
40
41
|
castor_extractor/file_checker/templates/generic_warehouse.py,sha256=3LREeiTsYsh5_wkuZost_frmMDp_K-jfiuod02vFMe8,2963
|
|
41
42
|
castor_extractor/knowledge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
+
castor_extractor/knowledge/confluence/__init__.py,sha256=pRT615pMDlB7Ifs09erVn2EdpZHgkvX5selemWU3VPE,129
|
|
44
|
+
castor_extractor/knowledge/confluence/assets.py,sha256=zv2G2LB8H0fKDbVJ4kHrAjbqehXI_K-wgd_ghSXGFvs,144
|
|
45
|
+
castor_extractor/knowledge/confluence/client/__init__.py,sha256=ALAzo0JEhxFzH2FnIO6HmtkAGS2_bGY8KXXMcTGV3aE,84
|
|
46
|
+
castor_extractor/knowledge/confluence/client/client.py,sha256=ZgAUlEGwpSN1QZAFGpU-7gob_wWI3wpBh1iTycxUZc4,1667
|
|
47
|
+
castor_extractor/knowledge/confluence/client/credentials.py,sha256=2LUjnCOMwq2NBrkHty99TpWlgyOOsYjwC9NeekZMH84,422
|
|
48
|
+
castor_extractor/knowledge/confluence/client/endpoints.py,sha256=b7PIvw9_W942L4zsEZa__KhZDTo4yt-CdIO0eas69TE,736
|
|
49
|
+
castor_extractor/knowledge/confluence/client/pagination.py,sha256=ty4meiMEujDVSiQyOJTibd-ReYyDyGezdFuk7EAGtMA,862
|
|
50
|
+
castor_extractor/knowledge/confluence/extract.py,sha256=0fnxqEQ1gLtNz0LANCvBHPCBN9hJSRMDWBgr0zNW45I,1545
|
|
42
51
|
castor_extractor/knowledge/notion/__init__.py,sha256=ZDmh0eNSxHf1zVPm0aYlKPci-vzOXhAgdsWjS2hdjh4,117
|
|
43
52
|
castor_extractor/knowledge/notion/assets.py,sha256=QHv1-pomt5UeN_prP2L6t_zJ-tDSqB8LgopkGAODYPQ,164
|
|
44
53
|
castor_extractor/knowledge/notion/client/__init__.py,sha256=CDPorBCethuNTEtpjvHGcWnWeVfqkEq-IbakWjDKATw,76
|
|
@@ -94,7 +103,7 @@ castor_extractor/utils/dbt/assets.py,sha256=JY1nKEGySZ84wNoe7dnizwAYw2q0t8NVaIfq
|
|
|
94
103
|
castor_extractor/utils/dbt/client.py,sha256=xBjbT-p99TXY850ooEAgjNp33yfGDwjWJRbXzeJoVaI,5538
|
|
95
104
|
castor_extractor/utils/dbt/client_test.py,sha256=FO_vpnECE-hoK0rZHbqDv17oaJj3-uPhFEqTrMPzUf4,4533
|
|
96
105
|
castor_extractor/utils/dbt/credentials.py,sha256=pGq7GqFQTw9TwN1DXSHC-0yJ2H6B_wMAbHyQTLqJVh0,543
|
|
97
|
-
castor_extractor/utils/deprecate.py,sha256=
|
|
106
|
+
castor_extractor/utils/deprecate.py,sha256=caXcCPStw9y97Bk_tu3pYVksfSj1x9ZyxnprNHJqHtA,830
|
|
98
107
|
castor_extractor/utils/env.py,sha256=TqdtB50U8LE0993WhhEhpy89TJrHbjtIKjvg6KQ-5q0,596
|
|
99
108
|
castor_extractor/utils/files.py,sha256=3C_u7P-kSZoOABVaKsuaf8lEhldRRxyxD27-K18_dEU,1545
|
|
100
109
|
castor_extractor/utils/files_test.py,sha256=omRT3XSjaSAywYUoLh1SGWqYzl4UwBYKSYA9_7mXd_E,1542
|
|
@@ -415,8 +424,8 @@ castor_extractor/warehouse/sqlserver/queries/table.sql,sha256=kbBQP-TdG5px1IVgyx
|
|
|
415
424
|
castor_extractor/warehouse/sqlserver/queries/user.sql,sha256=gOrZsMVypusR2dc4vwVs4E1a-CliRsr_UjnD2EbXs-A,94
|
|
416
425
|
castor_extractor/warehouse/sqlserver/query.py,sha256=j_d5-HMnzBouwGfywVZMRSSwbXzPvzDWlFCZmvxcoGQ,539
|
|
417
426
|
castor_extractor/warehouse/synapse/queries/column.sql,sha256=lNcFoIW3Y0PFOqoOzJEXmPvZvfAsY0AP63Mu2LuPzPo,1351
|
|
418
|
-
castor_extractor-0.
|
|
419
|
-
castor_extractor-0.
|
|
420
|
-
castor_extractor-0.
|
|
421
|
-
castor_extractor-0.
|
|
422
|
-
castor_extractor-0.
|
|
427
|
+
castor_extractor-0.21.1.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
428
|
+
castor_extractor-0.21.1.dist-info/METADATA,sha256=28gV2BAN9hz_TdzFHMxezHikWiOLwTczn0BwVKGrCy0,21575
|
|
429
|
+
castor_extractor-0.21.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
430
|
+
castor_extractor-0.21.1.dist-info/entry_points.txt,sha256=7aVSxc-_2dicp28Ow-S4y0p4wGoTm9zGmVptMvfLdw8,1649
|
|
431
|
+
castor_extractor-0.21.1.dist-info/RECORD,,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
2
|
castor-extract-bigquery=castor_extractor.commands.extract_bigquery:main
|
|
3
|
+
castor-extract-confluence=castor_extractor.commands.extract_confluence:main
|
|
3
4
|
castor-extract-databricks=castor_extractor.commands.extract_databricks:main
|
|
4
5
|
castor-extract-domo=castor_extractor.commands.extract_domo:main
|
|
5
6
|
castor-extract-looker=castor_extractor.commands.extract_looker:main
|
|
File without changes
|