jupyterlite-simple-cors-proxy 0.1.8__py3-none-any.whl → 0.1.10__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.
- jupyterlite_simple_cors_proxy/__init__.py +2 -2
- jupyterlite_simple_cors_proxy/cacheproxy.py +83 -0
- jupyterlite_simple_cors_proxy/proxy.py +4 -1
- {jupyterlite_simple_cors_proxy-0.1.8.dist-info → jupyterlite_simple_cors_proxy-0.1.10.dist-info}/METADATA +49 -1
- jupyterlite_simple_cors_proxy-0.1.10.dist-info/RECORD +9 -0
- jupyterlite_simple_cors_proxy-0.1.8.dist-info/RECORD +0 -8
- {jupyterlite_simple_cors_proxy-0.1.8.dist-info → jupyterlite_simple_cors_proxy-0.1.10.dist-info}/LICENSE +0 -0
- {jupyterlite_simple_cors_proxy-0.1.8.dist-info → jupyterlite_simple_cors_proxy-0.1.10.dist-info}/WHEEL +0 -0
- {jupyterlite_simple_cors_proxy-0.1.8.dist-info → jupyterlite_simple_cors_proxy-0.1.10.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
# File: jupyterlite_simple_cors_proxy/__init__.py
|
2
|
-
from .
|
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.
|
6
|
+
__version__ = "0.1.10"
|
7
7
|
__all__ = ["cors_proxy_get", "robust_get_request", "xurl", "furl"]
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# File: simple_cors_proxy/proxy.py
|
2
|
+
from urllib.parse import urlencode, quote
|
3
|
+
import requests
|
4
|
+
import requests_cache
|
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
|
+
# 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
|
+
|
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
|
40
|
+
|
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)
|
45
|
+
|
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)
|
60
|
+
|
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
|
70
|
+
|
71
|
+
# Create default instance
|
72
|
+
_default_proxy = CorsProxy()
|
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
|
79
|
+
|
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)
|
@@ -4,17 +4,20 @@ import requests
|
|
4
4
|
import io
|
5
5
|
|
6
6
|
import platform
|
7
|
+
|
7
8
|
PLATFORM = platform.system().lower()
|
8
9
|
|
10
|
+
|
9
11
|
def xurl(url, params=None, force=False):
|
10
12
|
"""Generate a proxied URL."""
|
11
|
-
if PLATFORM=="emscripten" or force:
|
13
|
+
if PLATFORM == "emscripten" or force:
|
12
14
|
if params:
|
13
15
|
url = f"{url}?{urlencode(params)}"
|
14
16
|
url = f"https://corsproxy.io/{quote(url)}"
|
15
17
|
|
16
18
|
return url
|
17
19
|
|
20
|
+
|
18
21
|
def furl(url, params=None, force=False):
|
19
22
|
"""Return file like object after calling the proxied URL."""
|
20
23
|
r = cors_proxy_get(url, params, force)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: jupyterlite-simple-cors-proxy
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.10
|
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
|
@@ -65,3 +65,51 @@ 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
|
+
```
|
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.*
|
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=QNqJ64TlAKsoaOKeVcRqeaibDiO3SpOyEakvenkuiuU,280
|
2
|
+
jupyterlite_simple_cors_proxy/cacheproxy.py,sha256=SzKQrflMbIJdHoDZ2dtRenGCAGMZEBSl_fs7sjIkiHk,2989
|
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.10.dist-info/LICENSE,sha256=Ogw7GUmeZIxmDNiKWsu_N07svNoGnPB7lWyiXHX_rMY,1074
|
6
|
+
jupyterlite_simple_cors_proxy-0.1.10.dist-info/METADATA,sha256=g2KklCts9AuEwEUEQ7EpaMh9JBAE8Nmb050_yZNqZbs,3059
|
7
|
+
jupyterlite_simple_cors_proxy-0.1.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
8
|
+
jupyterlite_simple_cors_proxy-0.1.10.dist-info/top_level.txt,sha256=Oh0oQrSmRnBq5u675coiKMbkb2ASg8AGF8ZiZTzUS5Q,30
|
9
|
+
jupyterlite_simple_cors_proxy-0.1.10.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
jupyterlite_simple_cors_proxy/__init__.py,sha256=fFGdcTl9-jFFAQJVrb1KXt8dh8NH-JcS79FvAtFT3T4,274
|
2
|
-
jupyterlite_simple_cors_proxy/fastf1_proxy.py,sha256=FglRogTIlSJvHOu6lFS3S-EHDb37M93aYjQpoKc1QYs,7614
|
3
|
-
jupyterlite_simple_cors_proxy/proxy.py,sha256=hF7SeLx7whBkE8m8bDUaelx2tKfLrSHA_Lp_auFtqeY,1341
|
4
|
-
jupyterlite_simple_cors_proxy-0.1.8.dist-info/LICENSE,sha256=Ogw7GUmeZIxmDNiKWsu_N07svNoGnPB7lWyiXHX_rMY,1074
|
5
|
-
jupyterlite_simple_cors_proxy-0.1.8.dist-info/METADATA,sha256=VCrtXTTVM4n0BsH-f2siz3s9SeWTDwGcVNJjvvfdz7k,1718
|
6
|
-
jupyterlite_simple_cors_proxy-0.1.8.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
7
|
-
jupyterlite_simple_cors_proxy-0.1.8.dist-info/top_level.txt,sha256=Oh0oQrSmRnBq5u675coiKMbkb2ASg8AGF8ZiZTzUS5Q,30
|
8
|
-
jupyterlite_simple_cors_proxy-0.1.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|