kaggle 1.7.4.2__py3-none-any.whl → 1.8.0__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.
Files changed (114) hide show
  1. kaggle/__init__.py +10 -6
  2. kaggle/api/kaggle_api.py +574 -585
  3. kaggle/api/kaggle_api_extended.py +5251 -4738
  4. kaggle/cli.py +1335 -1585
  5. kaggle/models/api_blob_type.py +3 -3
  6. kaggle/models/dataset_column.py +129 -129
  7. kaggle/models/dataset_new_request.py +130 -72
  8. kaggle/models/dataset_new_version_request.py +88 -56
  9. kaggle/models/dataset_update_settings_request.py +93 -59
  10. kaggle/models/kaggle_models_extended.py +169 -172
  11. kaggle/models/kernel_push_request.py +152 -100
  12. kaggle/models/model_instance_new_version_request.py +30 -30
  13. kaggle/models/model_instance_update_request.py +171 -71
  14. kaggle/models/model_new_instance_request.py +223 -88
  15. kaggle/models/model_new_request.py +61 -46
  16. kaggle/models/model_update_request.py +66 -48
  17. kaggle/models/start_blob_upload_request.py +146 -138
  18. kaggle/models/start_blob_upload_response.py +83 -78
  19. kaggle/models/upload_file.py +92 -96
  20. kaggle/test/test_authenticate.py +23 -23
  21. {kaggle-1.7.4.2.dist-info → kaggle-1.8.0.dist-info}/METADATA +11 -15
  22. kaggle-1.8.0.dist-info/RECORD +148 -0
  23. kagglesdk/__init__.py +5 -1
  24. kagglesdk/benchmarks/services/__init__.py +0 -0
  25. kagglesdk/benchmarks/services/benchmarks_api_service.py +19 -0
  26. kagglesdk/benchmarks/types/__init__.py +0 -0
  27. kagglesdk/benchmarks/types/benchmark_types.py +307 -0
  28. kagglesdk/benchmarks/types/benchmarks_api_service.py +243 -0
  29. kagglesdk/blobs/services/blob_api_service.py +1 -1
  30. kagglesdk/blobs/types/blob_api_service.py +2 -2
  31. kagglesdk/common/services/__init__.py +0 -0
  32. kagglesdk/common/services/operations_service.py +46 -0
  33. kagglesdk/common/types/file_download.py +1 -1
  34. kagglesdk/common/types/http_redirect.py +1 -1
  35. kagglesdk/common/types/operations.py +194 -0
  36. kagglesdk/common/types/operations_service.py +48 -0
  37. kagglesdk/community/__init__.py +0 -0
  38. kagglesdk/community/types/__init__.py +0 -0
  39. kagglesdk/community/types/content_enums.py +44 -0
  40. kagglesdk/community/types/organization.py +410 -0
  41. kagglesdk/competitions/services/competition_api_service.py +49 -12
  42. kagglesdk/competitions/types/competition.py +14 -0
  43. kagglesdk/competitions/types/competition_api_service.py +1639 -1275
  44. kagglesdk/competitions/types/search_competitions.py +28 -0
  45. kagglesdk/datasets/databundles/__init__.py +0 -0
  46. kagglesdk/datasets/databundles/types/__init__.py +0 -0
  47. kagglesdk/datasets/databundles/types/databundle_api_types.py +540 -0
  48. kagglesdk/datasets/services/dataset_api_service.py +39 -14
  49. kagglesdk/datasets/types/dataset_api_service.py +567 -297
  50. kagglesdk/datasets/types/dataset_enums.py +21 -0
  51. kagglesdk/datasets/types/dataset_service.py +145 -0
  52. kagglesdk/datasets/types/dataset_types.py +74 -74
  53. kagglesdk/datasets/types/search_datasets.py +6 -0
  54. kagglesdk/discussions/__init__.py +0 -0
  55. kagglesdk/discussions/types/__init__.py +0 -0
  56. kagglesdk/discussions/types/search_discussions.py +43 -0
  57. kagglesdk/discussions/types/writeup_enums.py +11 -0
  58. kagglesdk/education/services/education_api_service.py +1 -1
  59. kagglesdk/education/types/education_api_service.py +1 -1
  60. kagglesdk/kaggle_client.py +55 -20
  61. kagglesdk/kaggle_creds.py +148 -0
  62. kagglesdk/kaggle_env.py +89 -27
  63. kagglesdk/kaggle_http_client.py +235 -290
  64. kagglesdk/kaggle_oauth.py +200 -0
  65. kagglesdk/kaggle_object.py +298 -250
  66. kagglesdk/kernels/services/kernels_api_service.py +46 -9
  67. kagglesdk/kernels/types/kernels_api_service.py +658 -158
  68. kagglesdk/kernels/types/kernels_enums.py +6 -0
  69. kagglesdk/kernels/types/search_kernels.py +6 -0
  70. kagglesdk/licenses/__init__.py +0 -0
  71. kagglesdk/licenses/types/__init__.py +0 -0
  72. kagglesdk/licenses/types/licenses_types.py +182 -0
  73. kagglesdk/models/services/model_api_service.py +46 -21
  74. kagglesdk/models/types/model_api_service.py +1018 -652
  75. kagglesdk/models/types/model_enums.py +8 -0
  76. kagglesdk/models/types/model_service.py +71 -71
  77. kagglesdk/models/types/model_types.py +1057 -5
  78. kagglesdk/models/types/search_models.py +8 -0
  79. kagglesdk/search/__init__.py +0 -0
  80. kagglesdk/search/services/__init__.py +0 -0
  81. kagglesdk/search/services/search_api_service.py +19 -0
  82. kagglesdk/search/types/__init__.py +0 -0
  83. kagglesdk/search/types/search_api_service.py +2435 -0
  84. kagglesdk/search/types/search_content_shared.py +50 -0
  85. kagglesdk/search/types/search_enums.py +45 -0
  86. kagglesdk/search/types/search_service.py +303 -0
  87. kagglesdk/security/__init__.py +0 -0
  88. kagglesdk/security/services/__init__.py +0 -0
  89. kagglesdk/security/services/iam_service.py +31 -0
  90. kagglesdk/security/services/oauth_service.py +58 -0
  91. kagglesdk/security/types/__init__.py +0 -0
  92. kagglesdk/security/types/authentication.py +171 -0
  93. kagglesdk/security/types/iam_service.py +496 -0
  94. kagglesdk/security/types/oauth_service.py +1181 -0
  95. kagglesdk/security/types/roles.py +8 -0
  96. kagglesdk/security/types/security_types.py +159 -0
  97. kagglesdk/test/__init__.py +0 -0
  98. kagglesdk/test/test_client.py +20 -24
  99. kagglesdk/users/services/__init__.py +0 -0
  100. kagglesdk/users/services/account_service.py +31 -0
  101. kagglesdk/users/services/group_api_service.py +31 -0
  102. kagglesdk/users/types/account_service.py +345 -0
  103. kagglesdk/users/types/group_api_service.py +315 -0
  104. kagglesdk/users/types/group_types.py +165 -0
  105. kagglesdk/users/types/groups_enum.py +8 -0
  106. kagglesdk/users/types/progression_service.py +9 -0
  107. kagglesdk/users/types/search_users.py +23 -0
  108. kagglesdk/users/types/user_avatar.py +226 -0
  109. kaggle/configuration.py +0 -206
  110. kaggle-1.7.4.2.dist-info/RECORD +0 -89
  111. {kaggle-1.7.4.2.dist-info → kaggle-1.8.0.dist-info}/WHEEL +0 -0
  112. {kaggle-1.7.4.2.dist-info → kaggle-1.8.0.dist-info}/entry_points.txt +0 -0
  113. {kaggle-1.7.4.2.dist-info → kaggle-1.8.0.dist-info}/licenses/LICENSE.txt +0 -0
  114. {kaggle/test → kagglesdk/benchmarks}/__init__.py +0 -0
@@ -0,0 +1,148 @@
1
+ import json
2
+ import os
3
+ from datetime import datetime, timedelta, timezone
4
+ from kagglesdk.kaggle_client import KaggleClient
5
+ from kagglesdk.security.types.oauth_service import IntrospectTokenRequest
6
+ from kagglesdk.users.types.account_service import (
7
+ ApiVersion,
8
+ GenerateAccessTokenRequest,
9
+ GenerateAccessTokenResponse,
10
+ ExpireApiTokenRequest,
11
+ )
12
+
13
+
14
+ class KaggleCredentials:
15
+ DEFAULT_CREDENTIALS_FILE = "~/.kaggle/credentials.json"
16
+ DEFAULT_ACCESS_TOKEN_EXPIRATION = timedelta(hours=12)
17
+
18
+ def __init__(
19
+ self,
20
+ client: KaggleClient,
21
+ refresh_token: str = None,
22
+ access_token: str = None,
23
+ access_token_expiration: datetime = None,
24
+ username: str = None,
25
+ scopes: list[str] = None,
26
+ ):
27
+ self._client = client
28
+ self._refresh_token = refresh_token
29
+ self._access_token = access_token
30
+ self._access_token_expiration = access_token_expiration
31
+ self._username = username
32
+ self._scopes = scopes if scopes is not None else []
33
+
34
+ @classmethod
35
+ def load(cls, client: KaggleClient, file_path: str = None) -> "KaggleCredentials":
36
+ file_path = os.path.expanduser(file_path or KaggleCredentials.DEFAULT_CREDENTIALS_FILE)
37
+ if not os.path.exists(file_path):
38
+ return None
39
+
40
+ try:
41
+ with open(file_path, "r") as f:
42
+ data = json.load(f)
43
+ except (json.JSONDecodeError, KeyError):
44
+ return None
45
+
46
+ refresh_token = data.get("refresh_token")
47
+ if not refresh_token:
48
+ return None
49
+
50
+ access_token_expiration = data.get("access_token_expiration")
51
+ if access_token_expiration:
52
+ access_token_expiration = datetime.fromisoformat(access_token_expiration)
53
+ else:
54
+ access_token_expiration = None
55
+
56
+ return cls(
57
+ client=client,
58
+ refresh_token=refresh_token,
59
+ access_token=data.get("access_token"),
60
+ access_token_expiration=access_token_expiration,
61
+ username=data.get("username"),
62
+ scopes=data.get("scopes"),
63
+ )
64
+
65
+ def delete(self, file_path=DEFAULT_CREDENTIALS_FILE) -> None:
66
+ file_path = os.path.expanduser(file_path)
67
+ if os.path.exists(file_path):
68
+ os.remove(file_path)
69
+
70
+ def save(self, file_path=DEFAULT_CREDENTIALS_FILE) -> None:
71
+ if not self._refresh_token:
72
+ raise Exception("Missing refresh token")
73
+
74
+ file_path = os.path.expanduser(file_path)
75
+ dir_name = os.path.dirname(file_path)
76
+ if not os.path.exists(dir_name):
77
+ os.makedirs(dir_name)
78
+
79
+ data = {
80
+ "refresh_token": self._refresh_token,
81
+ "access_token": self._access_token or "",
82
+ "access_token_expiration": (
83
+ self._access_token_expiration.isoformat() if self._access_token_expiration else ""
84
+ ),
85
+ "username": self._username or "",
86
+ "scopes": self._scopes or [],
87
+ }
88
+
89
+ with open(file_path, "w") as f:
90
+ json.dump(data, f, indent=2)
91
+
92
+ try:
93
+ os.chmod(file_path, 0o600)
94
+ except OSError:
95
+ pass # Ignore errors, especially on Windows
96
+
97
+ def introspect(self) -> str:
98
+ request = IntrospectTokenRequest()
99
+ request.token = self._access_token
100
+ response = self._client.security.oauth_client.introspect_token(request)
101
+
102
+ if not response.active or not response.username:
103
+ raise Exception("Authentication failed.")
104
+
105
+ self._username = response.username
106
+ return response.username
107
+
108
+ def refresh_access_token(self) -> None:
109
+ if not self._refresh_token:
110
+ raise Exception("Missing refresh token")
111
+
112
+ response = self.generate_access_token()
113
+ self._access_token_expiration = datetime.now(timezone.utc) + timedelta(seconds=response.expires_in)
114
+ self._access_token = response.token
115
+ self.save()
116
+
117
+ def access_token_has_expired(self) -> bool:
118
+ return not self._access_token_expiration or self._access_token_expiration < datetime.now(
119
+ timezone.utc
120
+ ) - timedelta(minutes=30)
121
+
122
+ def get_access_token(self) -> str:
123
+ if not self._access_token or self.access_token_has_expired():
124
+ if not self._refresh_token:
125
+ return None
126
+ self.refresh_access_token()
127
+ return self._access_token
128
+
129
+ def generate_access_token(self, expiration_duration: timedelta = None) -> GenerateAccessTokenResponse:
130
+ if not self._refresh_token:
131
+ return None
132
+ request = GenerateAccessTokenRequest()
133
+ request.refresh_token = self._refresh_token
134
+ request.api_version = ApiVersion.API_VERSION_V1
135
+ request.expiration_duration = expiration_duration or KaggleCredentials.DEFAULT_ACCESS_TOKEN_EXPIRATION
136
+ return self._client.users.account_client.generate_access_token(request)
137
+
138
+ def revoke_token(self, reason: str) -> None:
139
+ if not self._refresh_token:
140
+ return
141
+ request = ExpireApiTokenRequest()
142
+ request.token = self._refresh_token
143
+ request.reason = reason
144
+ self._client.users.account_client.expire_api_token(request)
145
+ self.delete()
146
+
147
+ def get_username(self) -> str:
148
+ return self._username
kagglesdk/kaggle_env.py CHANGED
@@ -1,42 +1,104 @@
1
+ import logging
1
2
  import os
2
3
  from enum import Enum
4
+ from pathlib import Path
5
+
6
+ KAGGLE_NOTEBOOK_ENV_VAR_NAME = "KAGGLE_KERNEL_RUN_TYPE"
7
+ KAGGLE_DATA_PROXY_URL_ENV_VAR_NAME = "KAGGLE_DATA_PROXY_URL"
8
+ KAGGLE_API_V1_TOKEN_PATH = "KAGGLE_API_V1_TOKEN"
9
+
10
+
11
+ def get_logger():
12
+ return logging.getLogger(__name__)
3
13
 
4
14
 
5
15
  class KaggleEnv(Enum):
6
- LOCAL = 0 # localhost
7
- STAGING = 1 # staging.kaggle.com
8
- ADMIN = 2 # admin.kaggle.com
9
- QA = 3 # qa.kaggle.com
10
- # Direct prod access is not allowed to have IAP protection during testing, but we support basic auth.
11
- PROD = 4 # www.kaggle.com
16
+ LOCAL = 0 # localhost
17
+ STAGING = 1 # staging.kaggle.com
18
+ ADMIN = 2 # admin.kaggle.com
19
+ QA = 3 # qa.kaggle.com
20
+ PROD = 4 # api.kaggle.com
12
21
 
13
22
 
14
23
  _env_to_endpoint = {
15
- KaggleEnv.LOCAL: 'http://localhost',
16
- KaggleEnv.STAGING: 'https://staging.kaggle.com',
17
- KaggleEnv.ADMIN: 'https://admin.kaggle.com',
18
- KaggleEnv.QA: 'https://qa.kaggle.com',
19
- # See the comment above in KaggleEnv enum.
20
- KaggleEnv.PROD: "https://www.kaggle.com",
24
+ KaggleEnv.LOCAL: "http://localhost",
25
+ KaggleEnv.STAGING: "https://staging.kaggle.com",
26
+ KaggleEnv.ADMIN: "https://admin.kaggle.com",
27
+ KaggleEnv.QA: "https://qa.kaggle.com",
28
+ KaggleEnv.PROD: "https://api.kaggle.com",
21
29
  }
22
30
 
23
31
 
24
32
  def get_endpoint(env: KaggleEnv):
25
- return _env_to_endpoint[env]
33
+ return _env_to_endpoint[env]
26
34
 
27
35
 
28
36
  def get_env():
29
- env = os.getenv('KAGGLE_API_ENVIRONMENT')
30
- if env is None:
31
- raise Exception('Must specify KaggleEnv or set KAGGLE_API_ENVIRONMENT env var')
32
- if env == 'LOCALHOST':
33
- return KaggleEnv.LOCAL
34
- if env == 'ADMIN':
35
- return KaggleEnv.ADMIN
36
- if env == 'STAGING':
37
- return KaggleEnv.STAGING
38
- if env == 'QA':
39
- return KaggleEnv.QA
40
- if env == 'PROD':
41
- return KaggleEnv.PROD
42
- raise Exception(f'Unrecognized value in KAGGLE_API_ENVIRONMENT: "{env}"')
37
+ env = os.getenv("KAGGLE_API_ENVIRONMENT")
38
+ if env is None or env == "PROD":
39
+ return KaggleEnv.PROD
40
+ if env == "LOCALHOST":
41
+ return KaggleEnv.LOCAL
42
+ if env == "ADMIN":
43
+ return KaggleEnv.ADMIN
44
+ if env == "STAGING":
45
+ return KaggleEnv.STAGING
46
+ if env == "QA":
47
+ return KaggleEnv.QA
48
+ raise Exception(f'Unrecognized value in KAGGLE_API_ENVIRONMENT: "{env}"')
49
+
50
+
51
+ def is_in_kaggle_notebook() -> bool:
52
+ if os.getenv(KAGGLE_NOTEBOOK_ENV_VAR_NAME) is not None:
53
+ if os.getenv(KAGGLE_DATA_PROXY_URL_ENV_VAR_NAME) is None:
54
+ # Missing endpoint for the Jwt client
55
+ get_logger().warning(
56
+ "Can't use the Kaggle Cache. "
57
+ f"The '{KAGGLE_DATA_PROXY_URL_ENV_VAR_NAME}' environment variable is not set."
58
+ )
59
+ return False
60
+ return True
61
+ return False
62
+
63
+
64
+ def _get_access_token_from_file(path):
65
+ if not path:
66
+ return None
67
+
68
+ token_path = Path(path)
69
+ if not token_path.exists():
70
+ return None
71
+
72
+ token_value = token_path.read_text().strip()
73
+ if not token_value:
74
+ return None
75
+
76
+ get_logger().debug(f'Using access token from file: "{path}"')
77
+ return token_value
78
+
79
+
80
+ def get_access_token_from_env():
81
+ if is_in_kaggle_notebook():
82
+ token = _get_access_token_from_file(os.environ.get(KAGGLE_API_V1_TOKEN_PATH))
83
+ if token:
84
+ return (token, KAGGLE_API_V1_TOKEN_PATH)
85
+
86
+ access_token = os.environ.get("KAGGLE_API_TOKEN")
87
+ if access_token:
88
+ if Path(access_token).exists():
89
+ return (_get_access_token_from_file(access_token), "KAGGLE_API_TOKEN")
90
+ get_logger().debug(
91
+ "Using access token from KAGGLE_API_TOKEN environment variable"
92
+ )
93
+ return (access_token, "KAGGLE_API_TOKEN")
94
+
95
+ access_token = _get_access_token_from_file(os.path.expanduser("~/.kaggle/access_token"))
96
+ if access_token:
97
+ return (access_token, "access_token")
98
+
99
+ # Check ".txt" as well in case Windows users create the file with this extension.
100
+ access_token = _get_access_token_from_file(os.path.expanduser("~/.kaggle/access_token.txt"))
101
+ if access_token:
102
+ return (access_token, "access_token")
103
+
104
+ return (None, None)