jupyterlite-simple-cors-proxy 0.1.10__tar.gz → 0.1.12__tar.gz

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 (15) hide show
  1. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/PKG-INFO +2 -2
  2. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/README.md +1 -1
  3. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy/__init__.py +1 -1
  4. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy/cacheproxy.py +61 -11
  5. jupyterlite_simple_cors_proxy-0.1.12/jupyterlite_simple_cors_proxy/proxy.py +89 -0
  6. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy.egg-info/PKG-INFO +2 -2
  7. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/setup.py +1 -1
  8. jupyterlite_simple_cors_proxy-0.1.10/jupyterlite_simple_cors_proxy/proxy.py +0 -55
  9. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/LICENSE +0 -0
  10. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy/fastf1_proxy.py +0 -0
  11. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy.egg-info/SOURCES.txt +0 -0
  12. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy.egg-info/dependency_links.txt +0 -0
  13. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy.egg-info/requires.txt +0 -0
  14. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/jupyterlite_simple_cors_proxy.egg-info/top_level.txt +0 -0
  15. {jupyterlite_simple_cors_proxy-0.1.10 → jupyterlite_simple_cors_proxy-0.1.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jupyterlite-simple-cors-proxy
3
- Version: 0.1.10
3
+ Version: 0.1.12
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
@@ -87,7 +87,7 @@ Via `claude.ai`, the package is now further enriched.
87
87
 
88
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
89
 
90
- *I'm not convinced the following works in `pyodide` and `xeus-python` yet - `requests-cache` dependency issues etc.*
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
91
 
92
92
  ```python
93
93
  from simple_cors_proxy.proxy import CorsProxy
@@ -63,7 +63,7 @@ Via `claude.ai`, the package is now further enriched.
63
63
 
64
64
  *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 `/`.*
65
65
 
66
- *I'm not convinced the following works in `pyodide` and `xeus-python` yet - `requests-cache` dependency issues etc.*
66
+ *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`.*
67
67
 
68
68
  ```python
69
69
  from simple_cors_proxy.proxy import CorsProxy
@@ -3,5 +3,5 @@ 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.10"
6
+ __version__ = "0.1.11"
7
7
  __all__ = ["cors_proxy_get", "robust_get_request", "xurl", "furl"]
@@ -1,16 +1,22 @@
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
5
  import io
6
6
  import platform
7
7
  from typing import Optional, Union
8
8
 
9
9
  PLATFORM = platform.system().lower()
10
+ CORS_PROXIES = {
11
+ "corsproxyio": {"url": "https://corsproxy.io/?url={}", "quote": False},
12
+ "allorigins": {"url": "https://api.allorigins.win/raw?url={}", "quote": True},
13
+ "none": {"url": "{}", "quote": False},
14
+ }
15
+
10
16
 
11
17
  class CorsProxy:
12
18
  """CORS Proxy with optional caching support."""
13
-
19
+
14
20
  def __init__(self, use_cache: bool = False, **cache_kwargs):
15
21
  """
16
22
  Initialize the CORS proxy.
@@ -21,6 +27,7 @@ class CorsProxy:
21
27
  (e.g., cache_name, backend, expire_after)
22
28
  """
23
29
  if use_cache:
30
+ import requests_cache
24
31
  # Set some sensible defaults if not provided
25
32
  if 'cache_name' not in cache_kwargs:
26
33
  cache_kwargs['cache_name'] = 'cors_proxy_cache'
@@ -29,21 +36,61 @@ class CorsProxy:
29
36
  self.session = requests_cache.CachedSession(**cache_kwargs)
30
37
  else:
31
38
  self.session = requests
39
+ if "proxy" in cache_kwargs:
40
+ self.proxy = cache_kwargs["proxy"]
41
+ else:
42
+ self.proxy = "corsproxyio"
32
43
 
33
- def xurl(self, url: str, params: Optional[dict] = None, force: bool = False) -> str:
44
+ def apply_cors_proxy(self, url, proxy="corsproxyio"):
45
+ """
46
+ Apply a CORS proxy to the given URL.
47
+
48
+ Args:
49
+ url (str): The original URL to proxy
50
+ proxy (str): The proxy identifier to use from CORS_PROXIES
51
+
52
+ Returns:
53
+ str: The proxied URL
54
+ """
55
+ if proxy not in CORS_PROXIES:
56
+ raise ValueError(
57
+ f"Unknown proxy: {proxy}. Available proxies: {', '.join(CORS_PROXIES.keys())}"
58
+ )
59
+
60
+ proxy_config = CORS_PROXIES[proxy]
61
+
62
+ if proxy_config["quote"]:
63
+ url = proxy_config["url"].format(quote(url))
64
+ else:
65
+ url = proxy_config["url"].format(url)
66
+
67
+ return url
68
+
69
+ def xurl(
70
+ self,
71
+ url: str,
72
+ params: Optional[dict] = None,
73
+ force: bool = False,
74
+ proxy: str = "",
75
+ ) -> str:
34
76
  """Generate a proxied URL."""
35
77
  if PLATFORM == "emscripten" or force:
36
78
  if params:
37
79
  url = f"{url}?{urlencode(params)}"
38
- url = f"https://corsproxy.io/{quote(url)}"
80
+ # url = f"https://corsproxy.io/{quote(url)}"
81
+ if not proxy:
82
+ proxy = self.proxy
83
+ url = self.apply_cors_proxy(url, proxy=proxy)
39
84
  return url
40
85
 
41
- def furl(self, url: str, params: Optional[dict] = None, force: bool = False) -> io.BytesIO:
86
+ def furl(self, url: str, params: Optional[dict] = None, force: bool = False, proxy: str = "") -> io.BytesIO:
42
87
  """Return file like object after calling the proxied URL."""
43
- r = self.cors_proxy_get(url, params, force)
88
+ r = self.cors_proxy_get(url, params, force, proxy)
89
+ # TO DO - something to consider?
90
+ # https://simonwillison.net/2025/Jan/31/save-memory-with-bytesio/
44
91
  return io.BytesIO(r.content)
45
92
 
46
- def cors_proxy_get(self, url: str, params: Optional[dict] = None, force: bool = False) -> requests.Response:
93
+ def cors_proxy_get(self, url: str, params: Optional[dict] = None, force: bool = False, proxy: str = "corsproxyio") -> requests.Response:
47
94
  """
48
95
  CORS proxy for GET resources with requests-like response.
49
96
 
@@ -55,19 +102,22 @@ class CorsProxy:
55
102
  Returns:
56
103
  A requests response object.
57
104
  """
58
- proxy_url = self.xurl(url, params, force)
105
+ proxy_url = self.xurl(url, params, force), proxy
59
106
  return self.session.get(proxy_url)
60
107
 
61
- def robust_get_request(self, url: str, params: Optional[dict] = None) -> requests.Response:
108
+ def robust_get_request(
109
+ self, url: str, params: Optional[dict] = None, proxy: str = ""
110
+ ) -> requests.Response:
62
111
  """
63
112
  Try to make a simple request else fall back to a proxy.
64
113
  """
65
114
  try:
66
115
  r = self.session.get(url, params=params)
67
116
  except:
68
- r = self.cors_proxy_get(url, params=params)
117
+ r = self.cors_proxy_get(url, params=params, proxy=proxy)
69
118
  return r
70
119
 
120
+
71
121
  # Create default instance
72
122
  _default_proxy = CorsProxy()
73
123
 
@@ -80,4 +130,4 @@ robust_get_request = _default_proxy.robust_get_request
80
130
  # Convenience function to create a cached proxy
81
131
  def create_cached_proxy(**cache_kwargs):
82
132
  """Create a new CorsProxy instance with caching enabled."""
83
- return CorsProxy(use_cache=True, **cache_kwargs)
133
+ return CorsProxy(use_cache=True, **cache_kwargs)
@@ -0,0 +1,89 @@
1
+ # File: simple_cors_proxy/proxy.py
2
+ from urllib.parse import urlencode, quote
3
+ import requests
4
+ import io
5
+
6
+ import platform
7
+
8
+ PLATFORM = platform.system().lower()
9
+ CORS_PROXIES = {
10
+ "corsproxyio": {"url": "https://corsproxy.io/?url={}", "quote": False},
11
+ "allorigins": {"url": "https://api.allorigins.win/raw?url={}", "quote": True},
12
+ "none": {"url": "{}", "quote": False},
13
+ }
14
+
15
+
16
+ def apply_cors_proxy(url, proxy="corsproxyio"):
17
+ """
18
+ Apply a CORS proxy to the given URL.
19
+
20
+ Args:
21
+ url (str): The original URL to proxy
22
+ proxy (str): The proxy identifier to use from CORS_PROXIES
23
+
24
+ Returns:
25
+ str: The proxied URL
26
+ """
27
+ if proxy not in CORS_PROXIES:
28
+ raise ValueError(
29
+ f"Unknown proxy: {proxy}. Available proxies: {', '.join(CORS_PROXIES.keys())}"
30
+ )
31
+
32
+ proxy_config = CORS_PROXIES[proxy]
33
+
34
+ if proxy_config["quote"]:
35
+ url = proxy_config["url"].format(quote(url))
36
+ else:
37
+ url = proxy_config["url"].format(url)
38
+
39
+ return url
40
+
41
+
42
+ def xurl(url, params=None, force=False, proxy="corsproxyio"):
43
+ """Generate a proxied URL."""
44
+ if PLATFORM == "emscripten" or force:
45
+ if params:
46
+ url = f"{url}?{urlencode(params)}"
47
+ # url = f"https://corsproxy.io/{quote(url)}"
48
+ url = apply_cors_proxy(url, proxy=proxy)
49
+
50
+ return url
51
+
52
+
53
+ def furl(url, params=None, force=False, proxy="corsproxyio"):
54
+ """Return file like object after calling the proxied URL."""
55
+ r = cors_proxy_get(url, params, force, proxy=proxy)
56
+
57
+ # Return a file-like object from the JSON string
58
+ # TO DO - something to consider?
59
+ # https://simonwillison.net/2025/Jan/31/save-memory-with-bytesio/
60
+ return io.BytesIO(r.content)
61
+
62
+
63
+ def cors_proxy_get(url, params=None, force=False, proxy="corsproxyio"):
64
+ """
65
+ CORS proxy for GET resources with requests-like response.
66
+
67
+ Args:
68
+ url (str): The URL to fetch
69
+ params (dict, optional): Query parameters to include
70
+
71
+ Returns:
72
+ A requests response object.
73
+ """
74
+ proxy_url = xurl(url, params, force, proxy=proxy)
75
+
76
+ # Do a simple requests get and
77
+ # just pass through the entire response object
78
+ return requests.get(proxy_url)
79
+
80
+
81
+ def robust_get_request(url, params=None, proxy="corsproxyio"):
82
+ """
83
+ Try to make a simple request else fall back to a proxy.
84
+ """
85
+ try:
86
+ r = requests.get(url, params=params)
87
+ except:
88
+ r = cors_proxy_get(url, params=params, proxy=proxy)
89
+ return r
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jupyterlite-simple-cors-proxy
3
- Version: 0.1.10
3
+ Version: 0.1.12
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
@@ -87,7 +87,7 @@ Via `claude.ai`, the package is now further enriched.
87
87
 
88
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
89
 
90
- *I'm not convinced the following works in `pyodide` and `xeus-python` yet - `requests-cache` dependency issues etc.*
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
91
 
92
92
  ```python
93
93
  from simple_cors_proxy.proxy import CorsProxy
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
3
3
 
4
4
  setup(
5
5
  name="jupyterlite-simple-cors-proxy",
6
- version="0.1.10",
6
+ version="0.1.12",
7
7
  packages=find_packages(),
8
8
  install_requires=[
9
9
  "requests",
@@ -1,55 +0,0 @@
1
- # File: simple_cors_proxy/proxy.py
2
- from urllib.parse import urlencode, quote
3
- import requests
4
- import io
5
-
6
- import platform
7
-
8
- PLATFORM = platform.system().lower()
9
-
10
-
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
-
28
-
29
- def cors_proxy_get(url, params=None, force=False):
30
- """
31
- CORS proxy for GET resources with requests-like response.
32
-
33
- Args:
34
- url (str): The URL to fetch
35
- params (dict, optional): Query parameters to include
36
-
37
- Returns:
38
- A requests response object.
39
- """
40
- proxy_url = xurl(url, params, force)
41
-
42
- # Do a simple requests get and
43
- # just pass through the entire response object
44
- return requests.get(proxy_url)
45
-
46
-
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