jupyterlite-simple-cors-proxy 0.1.9__py3-none-any.whl → 0.1.11__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,7 +1,7 @@
1
1
  # File: jupyterlite_simple_cors_proxy/__init__.py
2
- from .proxy import cors_proxy_get, robust_get_request, xurl, furl
2
+ from .cacheproxy import cors_proxy_get, robust_get_request, xurl, furl
3
3
 
4
4
  # from .fastf1_proxy import enable_cors_proxy as fastf1_cors_proxy
5
5
 
6
- __version__ = "0.1.9"
6
+ __version__ = "0.1.11"
7
7
  __all__ = ["cors_proxy_get", "robust_get_request", "xurl", "furl"]
@@ -0,0 +1,84 @@
1
+ # File: simple_cors_proxy/proxy.py
2
+ from urllib.parse import urlencode, quote
3
+ import requests
4
+
5
+ import io
6
+ import platform
7
+ from typing import Optional, Union
8
+
9
+ PLATFORM = platform.system().lower()
10
+
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
+ import requests_cache
25
+ # Set some sensible defaults if not provided
26
+ if 'cache_name' not in cache_kwargs:
27
+ cache_kwargs['cache_name'] = 'cors_proxy_cache'
28
+ if 'expire_after' not in cache_kwargs:
29
+ cache_kwargs['expire_after'] = 3600 # 1 hour default
30
+ self.session = requests_cache.CachedSession(**cache_kwargs)
31
+ else:
32
+ self.session = requests
33
+
34
+ def xurl(self, url: str, params: Optional[dict] = None, force: bool = False) -> str:
35
+ """Generate a proxied URL."""
36
+ if PLATFORM == "emscripten" or force:
37
+ if params:
38
+ url = f"{url}?{urlencode(params)}"
39
+ url = f"https://corsproxy.io/{quote(url)}"
40
+ return url
41
+
42
+ def furl(self, url: str, params: Optional[dict] = None, force: bool = False) -> io.BytesIO:
43
+ """Return file like object after calling the proxied URL."""
44
+ r = self.cors_proxy_get(url, params, force)
45
+ return io.BytesIO(r.content)
46
+
47
+ def cors_proxy_get(self, url: str, params: Optional[dict] = None, force: bool = False) -> requests.Response:
48
+ """
49
+ CORS proxy for GET resources with requests-like response.
50
+
51
+ Args:
52
+ url: The URL to fetch
53
+ params: Query parameters to include
54
+ force: Force using the proxy even on non-emscripten platforms
55
+
56
+ Returns:
57
+ A requests response object.
58
+ """
59
+ proxy_url = self.xurl(url, params, force)
60
+ return self.session.get(proxy_url)
61
+
62
+ def robust_get_request(self, url: str, params: Optional[dict] = None) -> requests.Response:
63
+ """
64
+ Try to make a simple request else fall back to a proxy.
65
+ """
66
+ try:
67
+ r = self.session.get(url, params=params)
68
+ except:
69
+ r = self.cors_proxy_get(url, params=params)
70
+ return r
71
+
72
+ # Create default instance
73
+ _default_proxy = CorsProxy()
74
+
75
+ # Legacy function-based interface
76
+ xurl = _default_proxy.xurl
77
+ furl = _default_proxy.furl
78
+ cors_proxy_get = _default_proxy.cors_proxy_get
79
+ robust_get_request = _default_proxy.robust_get_request
80
+
81
+ # Convenience function to create a cached proxy
82
+ def create_cached_proxy(**cache_kwargs):
83
+ """Create a new CorsProxy instance with caching enabled."""
84
+ return CorsProxy(use_cache=True, **cache_kwargs)
@@ -1,83 +1,55 @@
1
1
  # File: simple_cors_proxy/proxy.py
2
2
  from urllib.parse import urlencode, quote
3
3
  import requests
4
- import requests_cache
5
4
  import io
5
+
6
6
  import platform
7
- from typing import Optional, Union
8
7
 
9
8
  PLATFORM = platform.system().lower()
10
9
 
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
32
10
 
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
11
+ def xurl(url, params=None, force=False):
12
+ """Generate a proxied URL."""
13
+ if PLATFORM == "emscripten" or force:
14
+ if params:
15
+ url = f"{url}?{urlencode(params)}"
16
+ url = f"https://corsproxy.io/{quote(url)}"
17
+
18
+ return url
19
+
20
+
21
+ def furl(url, params=None, force=False):
22
+ """Return file like object after calling the proxied URL."""
23
+ r = cors_proxy_get(url, params, force)
24
+
25
+ # Return a file-like object from the JSON string
26
+ return io.BytesIO(r.content)
27
+
40
28
 
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
+ def cors_proxy_get(url, params=None, force=False):
30
+ """
31
+ CORS proxy for GET resources with requests-like response.
45
32
 
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
+ Args:
34
+ url (str): The URL to fetch
35
+ params (dict, optional): Query parameters to include
60
36
 
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
37
+ Returns:
38
+ A requests response object.
39
+ """
40
+ proxy_url = xurl(url, params, force)
70
41
 
71
- # Create default instance
72
- _default_proxy = CorsProxy()
42
+ # Do a simple requests get and
43
+ # just pass through the entire response object
44
+ return requests.get(proxy_url)
73
45
 
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
79
46
 
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)
47
+ def robust_get_request(url, params=None):
48
+ """
49
+ Try to make a simple request else fall back to a proxy.
50
+ """
51
+ try:
52
+ r = requests.get(url, params=params)
53
+ except:
54
+ r = cors_proxy_get(url, params=params)
55
+ return r
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jupyterlite-simple-cors-proxy
3
- Version: 0.1.9
3
+ Version: 0.1.11
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
@@ -80,3 +80,36 @@ enable_cors_proxy(
80
80
  # proxy_url="https://corsproxy.io/",
81
81
  )
82
82
  ```
83
+
84
+ ## `CorsProxy` with cache facility
85
+
86
+ Via `claude.ai`, the package is now further enriched.
87
+
88
+ *Note that `pyodide` sqlite can't write to `/drive` so the cache path dir needs to be something like `/tmp` or a dir created on `/`.*
89
+
90
+ *I'm not convinced the following works in `pyodide` and `xeus-python` yet - `requests-cache` dependency issues etc. `requests-cache` has requirements `attrs`, `cattrs`,`platformdirs`, `url-normalize`.*
91
+
92
+ ```python
93
+ from simple_cors_proxy.proxy import CorsProxy
94
+
95
+ # Create a cached proxy instance
96
+ proxy = CorsProxy(use_cache=True, expire_after=3600) # Cache for 1 hour
97
+
98
+ # Use furl directly from your proxy instance
99
+ file_like = proxy.furl('https://example.com/somefile.csv')
100
+
101
+ #----
102
+ import pandas as pd
103
+ from simple_cors_proxy.cacheproxy import CorsProxy
104
+
105
+ proxy = CorsProxy(use_cache=True)
106
+ file_like = proxy.furl('https://example.com/data.csv')
107
+ df = pd.read_csv(file_like)
108
+
109
+ #----
110
+
111
+ from simple_cors_proxy.proxy import create_cached_proxy
112
+
113
+ proxy = create_cached_proxy(cache_name='my_cache', expire_after=86400) # Cache for 1 day
114
+ file_like = proxy.furl('https://example.com/somefile.csv')
115
+ ```
@@ -0,0 +1,9 @@
1
+ jupyterlite_simple_cors_proxy/__init__.py,sha256=vE2WKSaR1d-lu1EoKN3obCHFUB-oowD7I1jwEl5qvok,280
2
+ jupyterlite_simple_cors_proxy/cacheproxy.py,sha256=Rf3tR6knz70N-Bu9M-HhWJY88cI3WpW0MmIJBgpm008,3002
3
+ jupyterlite_simple_cors_proxy/fastf1_proxy.py,sha256=FglRogTIlSJvHOu6lFS3S-EHDb37M93aYjQpoKc1QYs,7614
4
+ jupyterlite_simple_cors_proxy/proxy.py,sha256=uFpevhGlkbcNqVb1d43uBrqVdvAbOQ2m1PLqxsML6BE,1346
5
+ jupyterlite_simple_cors_proxy-0.1.11.dist-info/LICENSE,sha256=Ogw7GUmeZIxmDNiKWsu_N07svNoGnPB7lWyiXHX_rMY,1074
6
+ jupyterlite_simple_cors_proxy-0.1.11.dist-info/METADATA,sha256=SMAXcQejInZ_6a00wZAqVS_NI8A_Kh-cfvBMIBDJUBo,3144
7
+ jupyterlite_simple_cors_proxy-0.1.11.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ jupyterlite_simple_cors_proxy-0.1.11.dist-info/top_level.txt,sha256=Oh0oQrSmRnBq5u675coiKMbkb2ASg8AGF8ZiZTzUS5Q,30
9
+ jupyterlite_simple_cors_proxy-0.1.11.dist-info/RECORD,,
@@ -1,8 +0,0 @@
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,,