jupyterlite-simple-cors-proxy 0.1.7__py3-none-any.whl → 0.1.9__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.
@@ -1,6 +1,7 @@
1
1
  # File: jupyterlite_simple_cors_proxy/__init__.py
2
2
  from .proxy import cors_proxy_get, robust_get_request, xurl, furl
3
- from .fastf1_proxy import enable_cors_proxy as fastf1_cors_proxy
4
3
 
5
- __version__ = "0.1.7"
6
- __all__ = ["cors_proxy_get", "robust_get_request", "xurl", "furl", "fastf1_cors_proxy"]
4
+ # from .fastf1_proxy import enable_cors_proxy as fastf1_cors_proxy
5
+
6
+ __version__ = "0.1.9"
7
+ __all__ = ["cors_proxy_get", "robust_get_request", "xurl", "furl"]
@@ -1,8 +1,8 @@
1
- #import functools
1
+ # import functools
2
2
  from urllib.parse import urlparse, quote
3
3
  import requests
4
- #import requests_cache
5
- #from requests_cache.session import CachedSession
4
+ # import requests_cache
5
+ # from requests_cache.session import CachedSession
6
6
  import fastf1
7
7
  import logging
8
8
  from typing import List, Optional, Dict, Any
@@ -19,7 +19,7 @@ class ProxyConfig:
19
19
 
20
20
  class CORSProxyPatcher:
21
21
  """Patches FastF1 to handle CORS requests through a proxy service."""
22
-
22
+
23
23
  def __init__(self, config: ProxyConfig = None):
24
24
  """
25
25
  Initialize the CORS proxy patcher for FastF1.
@@ -28,11 +28,14 @@ class CORSProxyPatcher:
28
28
  config (ProxyConfig): Configuration object for the proxy
29
29
  """
30
30
  self.config = config or ProxyConfig()
31
- self.domains = self.config.domains or []
32
-
31
+ self.domains = self.config.domains or [
32
+ "api.formula1.com",
33
+ "livetiming.formula1.com",
34
+ ]
35
+
33
36
  self._setup_logging()
34
37
  self._setup_session()
35
-
38
+
36
39
  def _setup_logging(self) -> None:
37
40
  """Configure logging based on debug setting."""
38
41
  self.logger = logging.getLogger('CORSProxyPatcher')
@@ -41,7 +44,7 @@ class CORSProxyPatcher:
41
44
  level=logging.DEBUG,
42
45
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
43
46
  )
44
-
47
+
45
48
  def _setup_session(self) -> None:
46
49
  """Set up the requests session with retry functionality."""
47
50
  self.session = requests.Session()
@@ -53,7 +56,7 @@ class CORSProxyPatcher:
53
56
  adapter = requests.adapters.HTTPAdapter(max_retries=retry_strategy)
54
57
  self.session.mount("http://", adapter)
55
58
  self.session.mount("https://", adapter)
56
-
59
+
57
60
  def should_proxy(self, url: str) -> bool:
58
61
  """
59
62
  Check if the URL should be routed through proxy based on domain.
@@ -69,7 +72,7 @@ class CORSProxyPatcher:
69
72
  if self.config.debug:
70
73
  self.logger.debug(f"URL: {url} - Should proxy: {should_proxy}")
71
74
  return should_proxy
72
-
75
+
73
76
  def get_proxied_url(self, url: str) -> str:
74
77
  """
75
78
  Get the proxied version of the URL if needed.
@@ -90,7 +93,7 @@ class CORSProxyPatcher:
90
93
  self.logger.debug(f"Proxied URL: {proxied}")
91
94
  return proxied
92
95
  return url
93
-
96
+
94
97
  def modify_headers(self, headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
95
98
  """
96
99
  Modify request headers to handle CORS.
@@ -149,19 +152,19 @@ class CORSProxyPatcher:
149
152
  modified_headers = self.modify_headers(headers)
150
153
  kwargs['headers'] = modified_headers
151
154
  kwargs['timeout'] = kwargs.get('timeout', self.config.timeout)
152
-
155
+
153
156
  try:
154
157
  if fastf1.Cache._requests_session_cached and not fastf1.Cache._tmp_disabled:
155
158
  session = fastf1.Cache._requests_session_cached
156
159
  else:
157
160
  session = self.session
158
-
161
+
159
162
  response = getattr(session, method)(proxied_url, **kwargs)
160
163
  response.raise_for_status()
161
-
164
+
162
165
  self.log_response(response, url)
163
166
  return response
164
-
167
+
165
168
  except requests.exceptions.RequestException as e:
166
169
  if self.config.debug:
167
170
  self.logger.error(f"Request failed: {str(e)}")
@@ -171,10 +174,10 @@ class CORSProxyPatcher:
171
174
  """Patch FastF1's request methods to use CORS proxy."""
172
175
  def wrapped_get(cls, url: str, headers: Optional[Dict[str, str]] = None, **kwargs: Any) -> requests.Response:
173
176
  return self.make_request('get', url, headers, **kwargs)
174
-
177
+
175
178
  def wrapped_post(cls, url: str, headers: Optional[Dict[str, str]] = None, **kwargs: Any) -> requests.Response:
176
179
  return self.make_request('post', url, headers, **kwargs)
177
-
180
+
178
181
  fastf1.Cache.requests_get = classmethod(wrapped_get)
179
182
  fastf1.Cache.requests_post = classmethod(wrapped_post)
180
183
 
@@ -205,8 +208,14 @@ def enable_cors_proxy(
205
208
  retry_count=retry_count,
206
209
  timeout=timeout
207
210
  )
208
-
211
+
209
212
  patcher = CORSProxyPatcher(config)
210
213
  patcher.patch_fastf1()
211
-
212
- return patcher
214
+
215
+ return patcher
216
+
217
+ # enable_cors_proxy(
218
+ # domains=["api.formula1.com", "livetiming.formula1.com"],
219
+ # debug=True,
220
+ # proxy_url="https://corsproxy.io/",
221
+ # )
@@ -1,52 +1,83 @@
1
1
  # File: simple_cors_proxy/proxy.py
2
2
  from urllib.parse import urlencode, quote
3
3
  import requests
4
+ import requests_cache
4
5
  import io
5
-
6
6
  import platform
7
- PLATFORM = platform.system().lower()
8
-
9
- def xurl(url, params=None, force=False):
10
- """Generate a proxied URL."""
11
- if PLATFORM=="emscripten" or force:
12
- if params:
13
- url = f"{url}?{urlencode(params)}"
14
- url = f"https://corsproxy.io/{quote(url)}"
7
+ from typing import Optional, Union
15
8
 
16
- return url
17
-
18
- def furl(url, params=None, force=False):
19
- """Return file like object after calling the proxied URL."""
20
- r = cors_proxy_get(url, params, force)
9
+ PLATFORM = platform.system().lower()
21
10
 
22
- # Return a file-like object from the JSON string
23
- return io.BytesIO(r.content)
11
+ class CorsProxy:
12
+ """CORS Proxy with optional caching support."""
13
+
14
+ def __init__(self, use_cache: bool = False, **cache_kwargs):
15
+ """
16
+ Initialize the CORS proxy.
17
+
18
+ Args:
19
+ use_cache: Whether to enable request caching
20
+ **cache_kwargs: Arguments passed to requests_cache.CachedSession
21
+ (e.g., cache_name, backend, expire_after)
22
+ """
23
+ if use_cache:
24
+ # Set some sensible defaults if not provided
25
+ if 'cache_name' not in cache_kwargs:
26
+ cache_kwargs['cache_name'] = 'cors_proxy_cache'
27
+ if 'expire_after' not in cache_kwargs:
28
+ cache_kwargs['expire_after'] = 3600 # 1 hour default
29
+ self.session = requests_cache.CachedSession(**cache_kwargs)
30
+ else:
31
+ self.session = requests
24
32
 
33
+ def xurl(self, url: str, params: Optional[dict] = None, force: bool = False) -> str:
34
+ """Generate a proxied URL."""
35
+ if PLATFORM == "emscripten" or force:
36
+ if params:
37
+ url = f"{url}?{urlencode(params)}"
38
+ url = f"https://corsproxy.io/{quote(url)}"
39
+ return url
25
40
 
26
- def cors_proxy_get(url, params=None, force=False):
27
- """
28
- CORS proxy for GET resources with requests-like response.
41
+ def furl(self, url: str, params: Optional[dict] = None, force: bool = False) -> io.BytesIO:
42
+ """Return file like object after calling the proxied URL."""
43
+ r = self.cors_proxy_get(url, params, force)
44
+ return io.BytesIO(r.content)
29
45
 
30
- Args:
31
- url (str): The URL to fetch
32
- params (dict, optional): Query parameters to include
46
+ def cors_proxy_get(self, url: str, params: Optional[dict] = None, force: bool = False) -> requests.Response:
47
+ """
48
+ CORS proxy for GET resources with requests-like response.
49
+
50
+ Args:
51
+ url: The URL to fetch
52
+ params: Query parameters to include
53
+ force: Force using the proxy even on non-emscripten platforms
54
+
55
+ Returns:
56
+ A requests response object.
57
+ """
58
+ proxy_url = self.xurl(url, params, force)
59
+ return self.session.get(proxy_url)
33
60
 
34
- Returns:
35
- A requests response object.
36
- """
37
- proxy_url = xurl(url, params, force)
61
+ def robust_get_request(self, url: str, params: Optional[dict] = None) -> requests.Response:
62
+ """
63
+ Try to make a simple request else fall back to a proxy.
64
+ """
65
+ try:
66
+ r = self.session.get(url, params=params)
67
+ except:
68
+ r = self.cors_proxy_get(url, params=params)
69
+ return r
38
70
 
39
- # Do a simple requests get and
40
- # just pass through the entire response object
41
- return requests.get(proxy_url)
71
+ # Create default instance
72
+ _default_proxy = CorsProxy()
42
73
 
74
+ # Legacy function-based interface
75
+ xurl = _default_proxy.xurl
76
+ furl = _default_proxy.furl
77
+ cors_proxy_get = _default_proxy.cors_proxy_get
78
+ robust_get_request = _default_proxy.robust_get_request
43
79
 
44
- def robust_get_request(url, params=None):
45
- """
46
- Try to make a simple request else fall back to a proxy.
47
- """
48
- try:
49
- r = requests.get(url, params=params)
50
- except:
51
- r = cors_proxy_get(url, params=params)
52
- return r
80
+ # Convenience function to create a cached proxy
81
+ def create_cached_proxy(**cache_kwargs):
82
+ """Create a new CorsProxy instance with caching enabled."""
83
+ return CorsProxy(use_cache=True, **cache_kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jupyterlite-simple-cors-proxy
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: A simple CORS proxy utility with requests-like response
5
5
  Home-page: https://github.com/innovationOUtside/jupyterlite-simple-cors-proxy
6
6
  Author: Tony Hirst
@@ -23,7 +23,7 @@ Dynamic: requires-python
23
23
  Dynamic: summary
24
24
 
25
25
  # jupyterlite-simple-cors-proxy
26
- Simple CORS proxy for making http requests from JupyterLite
26
+ Simple CORS proxy wrapper for making http requests from JupyterLite. Uses https://corsproxy.io/
27
27
 
28
28
  ## Installation
29
29
 
@@ -65,3 +65,18 @@ The `robust_get_request()` will first try a simple request, then a proxied reque
65
65
  - Simple CORS proxy wrapper
66
66
  - Requests response object
67
67
  - Support for URL parameters
68
+
69
+ ## `fastf1` cors proxy
70
+
71
+ A monkey patch for `fastf1` is provided as:
72
+
73
+ ```python
74
+ import fast f1
75
+ from jupyterlite_simple_cors_proxy.fastf1_proxy import enable_cors_proxy
76
+
77
+ enable_cors_proxy(
78
+ # domains=["api.formula1.com", "livetiming.formula1.com"],
79
+ # debug=True,
80
+ # proxy_url="https://corsproxy.io/",
81
+ )
82
+ ```
@@ -0,0 +1,8 @@
1
+ jupyterlite_simple_cors_proxy/__init__.py,sha256=yMbwL10DDWnXt2GVs_yOQLmlQtU2dtcHfTit62Nc04g,274
2
+ jupyterlite_simple_cors_proxy/fastf1_proxy.py,sha256=FglRogTIlSJvHOu6lFS3S-EHDb37M93aYjQpoKc1QYs,7614
3
+ jupyterlite_simple_cors_proxy/proxy.py,sha256=SzKQrflMbIJdHoDZ2dtRenGCAGMZEBSl_fs7sjIkiHk,2989
4
+ jupyterlite_simple_cors_proxy-0.1.9.dist-info/LICENSE,sha256=Ogw7GUmeZIxmDNiKWsu_N07svNoGnPB7lWyiXHX_rMY,1074
5
+ jupyterlite_simple_cors_proxy-0.1.9.dist-info/METADATA,sha256=HrfzXYCuKpPWh7zCDpbmbTZGRgCtGjpvH1Q0snUAQfU,2031
6
+ jupyterlite_simple_cors_proxy-0.1.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
+ jupyterlite_simple_cors_proxy-0.1.9.dist-info/top_level.txt,sha256=Oh0oQrSmRnBq5u675coiKMbkb2ASg8AGF8ZiZTzUS5Q,30
8
+ jupyterlite_simple_cors_proxy-0.1.9.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- jupyterlite_simple_cors_proxy/__init__.py,sha256=4IEZXGJ78nCMkOujvGFjwgNf3Rmv77u_lkZWufob5wU,292
2
- jupyterlite_simple_cors_proxy/fastf1_proxy.py,sha256=zsLspQjuj9gw4qbsFRydZvmfLelXUmb3gUOXjrGzQgs,7505
3
- jupyterlite_simple_cors_proxy/proxy.py,sha256=hF7SeLx7whBkE8m8bDUaelx2tKfLrSHA_Lp_auFtqeY,1341
4
- jupyterlite_simple_cors_proxy-0.1.7.dist-info/LICENSE,sha256=Ogw7GUmeZIxmDNiKWsu_N07svNoGnPB7lWyiXHX_rMY,1074
5
- jupyterlite_simple_cors_proxy-0.1.7.dist-info/METADATA,sha256=oXlGf3Dux_i1RHxUOF5IUOUqNECoZ-4EkLUkTn1UsWc,1682
6
- jupyterlite_simple_cors_proxy-0.1.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
- jupyterlite_simple_cors_proxy-0.1.7.dist-info/top_level.txt,sha256=Oh0oQrSmRnBq5u675coiKMbkb2ASg8AGF8ZiZTzUS5Q,30
8
- jupyterlite_simple_cors_proxy-0.1.7.dist-info/RECORD,,