Add Eleven Labs text-to-speech test and update Semantic Scholar notebook
Browse files- Created a new test file `test_elevenlabs.py` to implement Eleven Labs text-to-speech functionality with a sample Chinese text.
- Updated `test_semantic_scholar.ipynb` by removing redundant code cells, enhancing the structure, and adding explanations about API calls.
- Improved error handling and response parsing in the Semantic Scholar API testing section.
- .gitignore +1 -0
- tests/example_paper.json +5 -0
- tests/test_claude.ipynb +210 -0
- tests/test_eleven_labs.ipynb +24 -36
- tests/test_elevenlabs.py +38 -0
- tests/test_semantic_scholar.ipynb +95 -559
.gitignore
CHANGED
|
@@ -54,3 +54,4 @@ logs/
|
|
| 54 |
|
| 55 |
# Gradio
|
| 56 |
flagged/
|
|
|
|
|
|
| 54 |
|
| 55 |
# Gradio
|
| 56 |
flagged/
|
| 57 |
+
test_*.mp3
|
tests/example_paper.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"title": "Galactic Trajectories of Interstellar Objects 1I/'Oumuamua, 2I/Borisov, and 3I/Atlas",
|
| 3 |
+
"abstract": "The first interstellar objects, 1I/`Oumuamua, 2I/Borisov and 3I/ATLAS, were discovered over the past decade. We follow the trajectories of known interstellar objects in the gravitational potential of the Milky Way galaxy to constrain their possible origin. We perform Monte Carlo orbital integrations using 10,000 trajectory ensembles per object to properly account for measurement uncertainties in both object velocities and Solar motion parameters. We implement a Bayesian statistical framework that combines a Rayleigh-like likelihood function with star formation rate priors to infer stellar ages from the maximum vertical excursions ($z_{\\text{max}}$) of orbital trajectories. The likelihood function incorporates age-dependent velocity dispersions reflecting the thin-thick disk transition and dynamical heating over galactic history. Our Monte Carlo analysis yields median $z_{\\text{max}}$ values of 0.016 $\\pm$ 0.002 kpc for 1I/`Oumuamua, 0.121 $\\pm$ 0.010 kpc for 2I/Borisov, and 0.480 $\\pm$ 0.020 kpc for 3I/ATLAS. The Bayesian age inference indicates that 1I/`Oumuamua originated from a young stellar system (1.0 Gyr, 68\\% CI: 0.1-4.1 Gyr), 2I/Borisov from an intermediate-age population (3.8 Gyr, 68\\% CI: 1.8-5.9 Gyr), and 3I/ATLAS from an old thick-disk source (9.6 Gyr, 68\\% CI: 7.8-10.3 Gyr). These results demonstrate clear age discrimination where smaller vertical excursions correspond to younger stellar origins.",
|
| 4 |
+
"year": 2024
|
| 5 |
+
}
|
tests/test_claude.ipynb
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "02bd10a2",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"# Test Claude"
|
| 9 |
+
]
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"cell_type": "markdown",
|
| 13 |
+
"id": "2c62e2cb",
|
| 14 |
+
"metadata": {},
|
| 15 |
+
"source": [
|
| 16 |
+
"Assuming that the user has input the topic, and retrieved relevant articles (prepints)"
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"cell_type": "code",
|
| 21 |
+
"execution_count": 15,
|
| 22 |
+
"id": "15a030b4",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"outputs": [
|
| 25 |
+
{
|
| 26 |
+
"data": {
|
| 27 |
+
"text/plain": [
|
| 28 |
+
"{'title': \"Galactic Trajectories of Interstellar Objects 1I/'Oumuamua, 2I/Borisov, and 3I/Atlas\",\n",
|
| 29 |
+
" 'abstract': 'The first interstellar objects, 1I/`Oumuamua, 2I/Borisov and 3I/ATLAS, were discovered over the past decade. We follow the trajectories of known interstellar objects in the gravitational potential of the Milky Way galaxy to constrain their possible origin. We perform Monte Carlo orbital integrations using 10,000 trajectory ensembles per object to properly account for measurement uncertainties in both object velocities and Solar motion parameters. We implement a Bayesian statistical framework that combines a Rayleigh-like likelihood function with star formation rate priors to infer stellar ages from the maximum vertical excursions ($z_{\\\\text{max}}$) of orbital trajectories. The likelihood function incorporates age-dependent velocity dispersions reflecting the thin-thick disk transition and dynamical heating over galactic history. Our Monte Carlo analysis yields median $z_{\\\\text{max}}$ values of 0.016 $\\\\pm$ 0.002 kpc for 1I/`Oumuamua, 0.121 $\\\\pm$ 0.010 kpc for 2I/Borisov, and 0.480 $\\\\pm$ 0.020 kpc for 3I/ATLAS. The Bayesian age inference indicates that 1I/`Oumuamua originated from a young stellar system (1.0 Gyr, 68\\\\% CI: 0.1-4.1 Gyr), 2I/Borisov from an intermediate-age population (3.8 Gyr, 68\\\\% CI: 1.8-5.9 Gyr), and 3I/ATLAS from an old thick-disk source (9.6 Gyr, 68\\\\% CI: 7.8-10.3 Gyr). These results demonstrate clear age discrimination where smaller vertical excursions correspond to younger stellar origins.',\n",
|
| 30 |
+
" 'year': 2024}"
|
| 31 |
+
]
|
| 32 |
+
},
|
| 33 |
+
"execution_count": 15,
|
| 34 |
+
"metadata": {},
|
| 35 |
+
"output_type": "execute_result"
|
| 36 |
+
}
|
| 37 |
+
],
|
| 38 |
+
"source": [
|
| 39 |
+
"import json\n",
|
| 40 |
+
"\n",
|
| 41 |
+
"# for now, only title, abstract, year are used\n",
|
| 42 |
+
"with open(\"example_paper.json\", \"r\") as f:\n",
|
| 43 |
+
" paper_json = json.load(f)\n",
|
| 44 |
+
"\n",
|
| 45 |
+
"paper_json"
|
| 46 |
+
]
|
| 47 |
+
},
|
| 48 |
+
{
|
| 49 |
+
"cell_type": "code",
|
| 50 |
+
"execution_count": 16,
|
| 51 |
+
"id": "33e8e593",
|
| 52 |
+
"metadata": {},
|
| 53 |
+
"outputs": [],
|
| 54 |
+
"source": [
|
| 55 |
+
"# Initiate LLM (Anthropic)\n",
|
| 56 |
+
"import dotenv\n",
|
| 57 |
+
"import os\n",
|
| 58 |
+
"dotenv.load_dotenv()\n",
|
| 59 |
+
"ANTHROPIC_API_KEY = os.getenv(\"ANTHROPIC_API_KEY\")"
|
| 60 |
+
]
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"cell_type": "code",
|
| 64 |
+
"execution_count": 17,
|
| 65 |
+
"id": "029828d3",
|
| 66 |
+
"metadata": {},
|
| 67 |
+
"outputs": [],
|
| 68 |
+
"source": [
|
| 69 |
+
"output_language = \"Chinese\""
|
| 70 |
+
]
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"cell_type": "code",
|
| 74 |
+
"execution_count": 18,
|
| 75 |
+
"id": "1637f2a1",
|
| 76 |
+
"metadata": {},
|
| 77 |
+
"outputs": [],
|
| 78 |
+
"source": [
|
| 79 |
+
"prompt = f\"\"\"\n",
|
| 80 |
+
"Summarize this research paper in clear, accessible language:\n",
|
| 81 |
+
"\n",
|
| 82 |
+
"Title: {paper_json[\"title\"]}\n",
|
| 83 |
+
"Year: {paper_json[\"year\"]}\n",
|
| 84 |
+
"\n",
|
| 85 |
+
"Abstract:\n",
|
| 86 |
+
"{paper_json[\"abstract\"]}\n",
|
| 87 |
+
"\n",
|
| 88 |
+
"Provide a concise summary (2-3 paragraphs) that:\n",
|
| 89 |
+
"1. Explains what problem the research addresses\n",
|
| 90 |
+
"2. Describes the key methodology or approach\n",
|
| 91 |
+
"3. Highlights the main findings and their significance\n",
|
| 92 |
+
"\n",
|
| 93 |
+
"Write for a general audience interested in science.\n",
|
| 94 |
+
"\n",
|
| 95 |
+
"Please respond in {output_language}.\n",
|
| 96 |
+
"\n",
|
| 97 |
+
"\"\"\""
|
| 98 |
+
]
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"cell_type": "code",
|
| 102 |
+
"execution_count": 19,
|
| 103 |
+
"id": "91adcaad",
|
| 104 |
+
"metadata": {},
|
| 105 |
+
"outputs": [
|
| 106 |
+
{
|
| 107 |
+
"name": "stdout",
|
| 108 |
+
"output_type": "stream",
|
| 109 |
+
"text": [
|
| 110 |
+
"# 星际物体银河轨迹研究总结\n",
|
| 111 |
+
"\n",
|
| 112 |
+
"## 研究问题\n",
|
| 113 |
+
"\n",
|
| 114 |
+
"本研究针对一个引人入胜的天文谜题:过去十年里发现的三个星际物体(`Oumuamua、Borisov和ATLAS)来自哪里?这些物体来自我们太阳系之外,穿过银河系。科学家们想通过追踪它们在银河系中的运动轨迹,推断出它们的起源和年龄。\n",
|
| 115 |
+
"\n",
|
| 116 |
+
"## 研究方法\n",
|
| 117 |
+
"\n",
|
| 118 |
+
"研究人员采用了一种精密的计算方法。他们对每个物体进行了10,000次轨道模拟,以考虑测量数据中的不确定性。关键创新在于结合贝叶斯统计框架——一种处理概率的数学方法——与银河系恒星形成速率数据。通过分析这些物体在银河系中垂直方向的最大偏离距离,结合考虑不同年代恒星的运动特性差异,他们能够推断出这些物体的起源年代。\n",
|
| 119 |
+
"\n",
|
| 120 |
+
"## 主要发现\n",
|
| 121 |
+
"\n",
|
| 122 |
+
"研究结果显示出清晰的模式:`Oumuamua来自非常年轻的恒星系统(约10亿年),Borisov来自中等年龄的恒星(约38亿年),而ATLAS来自非常古老的银河系厚盘结构(约96亿年)。这一发现意义重大,因为它表明通过测量星际物体的银河轨道特征,科学家们可以推断这些神秘访客的起源时间和源头恒星的年龄——为理解宇宙中物质如何在星系间传播提供了新的洞见。\n"
|
| 123 |
+
]
|
| 124 |
+
}
|
| 125 |
+
],
|
| 126 |
+
"source": [
|
| 127 |
+
"import anthropic\n",
|
| 128 |
+
"\n",
|
| 129 |
+
"client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)\n",
|
| 130 |
+
"message = client.messages.create(\n",
|
| 131 |
+
" model=\"claude-haiku-4-5\",\n",
|
| 132 |
+
" max_tokens=4000,\n",
|
| 133 |
+
" messages=[\n",
|
| 134 |
+
" {\n",
|
| 135 |
+
" \"role\": \"user\",\n",
|
| 136 |
+
" \"content\": prompt\n",
|
| 137 |
+
" }\n",
|
| 138 |
+
" ]\n",
|
| 139 |
+
")\n",
|
| 140 |
+
"\n",
|
| 141 |
+
"print(message.content[0].text)"
|
| 142 |
+
]
|
| 143 |
+
},
|
| 144 |
+
{
|
| 145 |
+
"cell_type": "code",
|
| 146 |
+
"execution_count": null,
|
| 147 |
+
"id": "6f701bb5",
|
| 148 |
+
"metadata": {},
|
| 149 |
+
"outputs": [],
|
| 150 |
+
"source": []
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"cell_type": "code",
|
| 154 |
+
"execution_count": 20,
|
| 155 |
+
"id": "1fe86509",
|
| 156 |
+
"metadata": {},
|
| 157 |
+
"outputs": [
|
| 158 |
+
{
|
| 159 |
+
"data": {
|
| 160 |
+
"text/markdown": [
|
| 161 |
+
"# 星际物体银河轨迹研究总结\n",
|
| 162 |
+
"\n",
|
| 163 |
+
"## 研究问题\n",
|
| 164 |
+
"\n",
|
| 165 |
+
"本研究针对一个引人入胜的天文谜题:过去十年里发现的三个星际物体(`Oumuamua、Borisov和ATLAS)来自哪里?这些物体来自我们太阳系之外,穿过银河系。科学家们想通过追踪它们在银河系中的运动轨迹,推断出它们的起源和年龄。\n",
|
| 166 |
+
"\n",
|
| 167 |
+
"## 研究方法\n",
|
| 168 |
+
"\n",
|
| 169 |
+
"研究人员采用了一种精密的计算方法。他们对每个物体进行了10,000次轨道模拟,以考虑测量数据中的不确定性。关键创新在于结合贝叶斯统计框架——一种处理概率的数学方法——与银河系恒星形成速率数据。通过分析这些物体在银河系中垂直方向的最大偏离距离,结合考虑不同年代恒星的运动特性差异,他们能够推断出这些物体的起源年代。\n",
|
| 170 |
+
"\n",
|
| 171 |
+
"## 主要发现\n",
|
| 172 |
+
"\n",
|
| 173 |
+
"研究结果显示出清晰的模式:`Oumuamua来自非常年轻的恒星系统(约10亿年),Borisov来自中等年龄的恒星(约38亿年),而ATLAS来自非常古老的银河系厚盘结构(约96亿年)。这一发现意义重大,因为它表明通过测量星际物体的银河轨道特征,科学家们可以推断这些神秘访客的起源时间和源头恒星的年龄——为理解宇宙中物质如何在星系间传播提供了新的洞见。"
|
| 174 |
+
],
|
| 175 |
+
"text/plain": [
|
| 176 |
+
"<IPython.core.display.Markdown object>"
|
| 177 |
+
]
|
| 178 |
+
},
|
| 179 |
+
"metadata": {},
|
| 180 |
+
"output_type": "display_data"
|
| 181 |
+
}
|
| 182 |
+
],
|
| 183 |
+
"source": [
|
| 184 |
+
"from IPython.display import Markdown, display\n",
|
| 185 |
+
"display(Markdown(message.content[0].text))"
|
| 186 |
+
]
|
| 187 |
+
}
|
| 188 |
+
],
|
| 189 |
+
"metadata": {
|
| 190 |
+
"kernelspec": {
|
| 191 |
+
"display_name": "science-storyteller",
|
| 192 |
+
"language": "python",
|
| 193 |
+
"name": "python3"
|
| 194 |
+
},
|
| 195 |
+
"language_info": {
|
| 196 |
+
"codemirror_mode": {
|
| 197 |
+
"name": "ipython",
|
| 198 |
+
"version": 3
|
| 199 |
+
},
|
| 200 |
+
"file_extension": ".py",
|
| 201 |
+
"mimetype": "text/x-python",
|
| 202 |
+
"name": "python",
|
| 203 |
+
"nbconvert_exporter": "python",
|
| 204 |
+
"pygments_lexer": "ipython3",
|
| 205 |
+
"version": "3.10.19"
|
| 206 |
+
}
|
| 207 |
+
},
|
| 208 |
+
"nbformat": 4,
|
| 209 |
+
"nbformat_minor": 5
|
| 210 |
+
}
|
tests/test_eleven_labs.ipynb
CHANGED
|
@@ -10,7 +10,7 @@
|
|
| 10 |
},
|
| 11 |
{
|
| 12 |
"cell_type": "code",
|
| 13 |
-
"execution_count":
|
| 14 |
"id": "8b55bb7a",
|
| 15 |
"metadata": {},
|
| 16 |
"outputs": [
|
|
@@ -30,27 +30,26 @@
|
|
| 30 |
},
|
| 31 |
{
|
| 32 |
"cell_type": "code",
|
| 33 |
-
"execution_count":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
"id": "99d19e18",
|
| 35 |
"metadata": {},
|
| 36 |
-
"outputs": [
|
| 37 |
-
{
|
| 38 |
-
"ename": "ApiError",
|
| 39 |
-
"evalue": "headers: {'date': 'Thu, 20 Nov 2025 09:03:54 GMT', 'server': 'uvicorn', 'content-length': '476', 'content-type': 'application/json', 'access-control-allow-origin': '*', 'access-control-allow-headers': '*', 'access-control-allow-methods': 'POST, PATCH, OPTIONS, DELETE, GET, PUT', 'access-control-max-age': '600', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'x-trace-id': '12db0c07c0d547fd38e5d67fb6d27e0c', 'x-region': 'us-central1', 'via': '1.1 google, 1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 401, body: {'detail': {'status': 'detected_unusual_activity', 'message': 'Unusual activity detected. Free Tier usage disabled. If you are using a proxy/VPN you might need to purchase a Paid Plan to not trigger our abuse detectors. Free Tier only works if users do not abuse it, for example by creating multiple free accounts. If we notice that many people try to abuse it, we will need to reconsider Free Tier altogether. \\nPlease play fair and purchase any Paid Subscription to continue.'}}",
|
| 40 |
-
"output_type": "error",
|
| 41 |
-
"traceback": [
|
| 42 |
-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
| 43 |
-
"\u001b[0;31mApiError\u001b[0m Traceback (most recent call last)",
|
| 44 |
-
"Cell \u001b[0;32mIn[12], line 15\u001b[0m\n\u001b[1;32m 4\u001b[0m client \u001b[38;5;241m=\u001b[39m ElevenLabs(\n\u001b[1;32m 5\u001b[0m api_key\u001b[38;5;241m=\u001b[39mELEVENLABS_API_KEY\n\u001b[1;32m 6\u001b[0m )\n\u001b[1;32m 8\u001b[0m audio \u001b[38;5;241m=\u001b[39m client\u001b[38;5;241m.\u001b[39mtext_to_speech\u001b[38;5;241m.\u001b[39mconvert(\n\u001b[1;32m 9\u001b[0m text\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe first move is what sets everything in motion.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 10\u001b[0m voice_id\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mJBFqnCBsd6RMkjVDRZzb\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 11\u001b[0m model_id\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124meleven_multilingual_v2\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 12\u001b[0m output_format\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmp3_44100_128\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 13\u001b[0m )\n\u001b[0;32m---> 15\u001b[0m \u001b[43mplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43maudio\u001b[49m\u001b[43m)\u001b[49m\n",
|
| 45 |
-
"File \u001b[0;32m/home/user/app/.venv/lib/python3.10/site-packages/elevenlabs/play.py:19\u001b[0m, in \u001b[0;36mplay\u001b[0;34m(audio, notebook, use_ffmpeg)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mplay\u001b[39m(\n\u001b[1;32m 14\u001b[0m audio: Union[\u001b[38;5;28mbytes\u001b[39m, Iterator[\u001b[38;5;28mbytes\u001b[39m]], \n\u001b[1;32m 15\u001b[0m notebook: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m, \n\u001b[1;32m 16\u001b[0m use_ffmpeg: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 17\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 18\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(audio, Iterator):\n\u001b[0;32m---> 19\u001b[0m audio \u001b[38;5;241m=\u001b[39m \u001b[38;5;124;43mb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43maudio\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m notebook:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
| 46 |
-
"File \u001b[0;32m/home/user/app/.venv/lib/python3.10/site-packages/elevenlabs/text_to_speech/client.py:157\u001b[0m, in \u001b[0;36mTextToSpeechClient.convert\u001b[0;34m(self, voice_id, text, enable_logging, optimize_streaming_latency, output_format, model_id, language_code, voice_settings, pronunciation_dictionary_locators, seed, previous_text, next_text, previous_request_ids, next_request_ids, use_pvc_as_ivc, apply_text_normalization, apply_language_text_normalization, request_options)\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mconvert\u001b[39m(\n\u001b[1;32m 49\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 50\u001b[0m voice_id: \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 70\u001b[0m request_options: typing\u001b[38;5;241m.\u001b[39mOptional[RequestOptions] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 71\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m typing\u001b[38;5;241m.\u001b[39mIterator[\u001b[38;5;28mbytes\u001b[39m]:\n\u001b[1;32m 72\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 73\u001b[0m \u001b[38;5;124;03m Converts text into speech using a voice of your choice and returns audio.\u001b[39;00m\n\u001b[1;32m 74\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[38;5;124;03m )\u001b[39;00m\n\u001b[1;32m 156\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 157\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_raw_client\u001b[38;5;241m.\u001b[39mconvert(\n\u001b[1;32m 158\u001b[0m voice_id,\n\u001b[1;32m 159\u001b[0m text\u001b[38;5;241m=\u001b[39mtext,\n\u001b[1;32m 160\u001b[0m enable_logging\u001b[38;5;241m=\u001b[39menable_logging,\n\u001b[1;32m 161\u001b[0m optimize_streaming_latency\u001b[38;5;241m=\u001b[39moptimize_streaming_latency,\n\u001b[1;32m 162\u001b[0m output_format\u001b[38;5;241m=\u001b[39moutput_format,\n\u001b[1;32m 163\u001b[0m model_id\u001b[38;5;241m=\u001b[39mmodel_id,\n\u001b[1;32m 164\u001b[0m language_code\u001b[38;5;241m=\u001b[39mlanguage_code,\n\u001b[1;32m 165\u001b[0m voice_settings\u001b[38;5;241m=\u001b[39mvoice_settings,\n\u001b[1;32m 166\u001b[0m pronunciation_dictionary_locators\u001b[38;5;241m=\u001b[39mpronunciation_dictionary_locators,\n\u001b[1;32m 167\u001b[0m seed\u001b[38;5;241m=\u001b[39mseed,\n\u001b[1;32m 168\u001b[0m previous_text\u001b[38;5;241m=\u001b[39mprevious_text,\n\u001b[1;32m 169\u001b[0m next_text\u001b[38;5;241m=\u001b[39mnext_text,\n\u001b[1;32m 170\u001b[0m previous_request_ids\u001b[38;5;241m=\u001b[39mprevious_request_ids,\n\u001b[1;32m 171\u001b[0m next_request_ids\u001b[38;5;241m=\u001b[39mnext_request_ids,\n\u001b[1;32m 172\u001b[0m use_pvc_as_ivc\u001b[38;5;241m=\u001b[39muse_pvc_as_ivc,\n\u001b[1;32m 173\u001b[0m apply_text_normalization\u001b[38;5;241m=\u001b[39mapply_text_normalization,\n\u001b[1;32m 174\u001b[0m apply_language_text_normalization\u001b[38;5;241m=\u001b[39mapply_language_text_normalization,\n\u001b[1;32m 175\u001b[0m request_options\u001b[38;5;241m=\u001b[39mrequest_options,\n\u001b[1;32m 176\u001b[0m ) \u001b[38;5;28;01mas\u001b[39;00m r:\n\u001b[1;32m 177\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m r\u001b[38;5;241m.\u001b[39mdata\n",
|
| 47 |
-
"File \u001b[0;32m/usr/local/lib/python3.10/contextlib.py:135\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__enter__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 133\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkwds, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc\n\u001b[1;32m 134\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 135\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m 137\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenerator didn\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt yield\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n",
|
| 48 |
-
"File \u001b[0;32m/home/user/app/.venv/lib/python3.10/site-packages/elevenlabs/text_to_speech/raw_client.py:204\u001b[0m, in \u001b[0;36mRawTextToSpeechClient.convert\u001b[0;34m(self, voice_id, text, enable_logging, optimize_streaming_latency, output_format, model_id, language_code, voice_settings, pronunciation_dictionary_locators, seed, previous_text, next_text, previous_request_ids, next_request_ids, use_pvc_as_ivc, apply_text_normalization, apply_language_text_normalization, request_options)\u001b[0m\n\u001b[1;32m 199\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ApiError(\n\u001b[1;32m 200\u001b[0m status_code\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mstatus_code, headers\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mdict\u001b[39m(_response\u001b[38;5;241m.\u001b[39mheaders), body\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mtext\n\u001b[1;32m 201\u001b[0m )\n\u001b[1;32m 202\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ApiError(status_code\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mstatus_code, headers\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mdict\u001b[39m(_response\u001b[38;5;241m.\u001b[39mheaders), body\u001b[38;5;241m=\u001b[39m_response_json)\n\u001b[0;32m--> 204\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m \u001b[43m_stream\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
|
| 49 |
-
"File \u001b[0;32m/home/user/app/.venv/lib/python3.10/site-packages/elevenlabs/text_to_speech/raw_client.py:202\u001b[0m, in \u001b[0;36mRawTextToSpeechClient.convert.<locals>._stream\u001b[0;34m()\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m JSONDecodeError:\n\u001b[1;32m 199\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ApiError(\n\u001b[1;32m 200\u001b[0m status_code\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mstatus_code, headers\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mdict\u001b[39m(_response\u001b[38;5;241m.\u001b[39mheaders), body\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mtext\n\u001b[1;32m 201\u001b[0m )\n\u001b[0;32m--> 202\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ApiError(status_code\u001b[38;5;241m=\u001b[39m_response\u001b[38;5;241m.\u001b[39mstatus_code, headers\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mdict\u001b[39m(_response\u001b[38;5;241m.\u001b[39mheaders), body\u001b[38;5;241m=\u001b[39m_response_json)\n",
|
| 50 |
-
"\u001b[0;31mApiError\u001b[0m: headers: {'date': 'Thu, 20 Nov 2025 09:03:54 GMT', 'server': 'uvicorn', 'content-length': '476', 'content-type': 'application/json', 'access-control-allow-origin': '*', 'access-control-allow-headers': '*', 'access-control-allow-methods': 'POST, PATCH, OPTIONS, DELETE, GET, PUT', 'access-control-max-age': '600', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'x-trace-id': '12db0c07c0d547fd38e5d67fb6d27e0c', 'x-region': 'us-central1', 'via': '1.1 google, 1.1 google', 'alt-svc': 'h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000'}, status_code: 401, body: {'detail': {'status': 'detected_unusual_activity', 'message': 'Unusual activity detected. Free Tier usage disabled. If you are using a proxy/VPN you might need to purchase a Paid Plan to not trigger our abuse detectors. Free Tier only works if users do not abuse it, for example by creating multiple free accounts. If we notice that many people try to abuse it, we will need to reconsider Free Tier altogether. \\nPlease play fair and purchase any Paid Subscription to continue.'}}"
|
| 51 |
-
]
|
| 52 |
-
}
|
| 53 |
-
],
|
| 54 |
"source": [
|
| 55 |
"from elevenlabs.client import ElevenLabs\n",
|
| 56 |
"from elevenlabs.play import play\n",
|
|
@@ -60,7 +59,7 @@
|
|
| 60 |
")\n",
|
| 61 |
"\n",
|
| 62 |
"audio = client.text_to_speech.convert(\n",
|
| 63 |
-
" text
|
| 64 |
" voice_id=\"JBFqnCBsd6RMkjVDRZzb\",\n",
|
| 65 |
" model_id=\"eleven_multilingual_v2\",\n",
|
| 66 |
" output_format=\"mp3_44100_128\",\n",
|
|
@@ -71,29 +70,18 @@
|
|
| 71 |
},
|
| 72 |
{
|
| 73 |
"cell_type": "code",
|
| 74 |
-
"execution_count":
|
| 75 |
"id": "ad8c93d3",
|
| 76 |
"metadata": {},
|
| 77 |
-
"outputs": [
|
| 78 |
-
{
|
| 79 |
-
"data": {
|
| 80 |
-
"text/plain": [
|
| 81 |
-
"<generator object TextToSpeechClient.convert at 0x7f701a7f82e0>"
|
| 82 |
-
]
|
| 83 |
-
},
|
| 84 |
-
"execution_count": 11,
|
| 85 |
-
"metadata": {},
|
| 86 |
-
"output_type": "execute_result"
|
| 87 |
-
}
|
| 88 |
-
],
|
| 89 |
"source": [
|
| 90 |
-
"audio
|
| 91 |
]
|
| 92 |
}
|
| 93 |
],
|
| 94 |
"metadata": {
|
| 95 |
"kernelspec": {
|
| 96 |
-
"display_name": "
|
| 97 |
"language": "python",
|
| 98 |
"name": "python3"
|
| 99 |
},
|
|
|
|
| 10 |
},
|
| 11 |
{
|
| 12 |
"cell_type": "code",
|
| 13 |
+
"execution_count": 1,
|
| 14 |
"id": "8b55bb7a",
|
| 15 |
"metadata": {},
|
| 16 |
"outputs": [
|
|
|
|
| 30 |
},
|
| 31 |
{
|
| 32 |
"cell_type": "code",
|
| 33 |
+
"execution_count": null,
|
| 34 |
+
"id": "5ba0c84e",
|
| 35 |
+
"metadata": {},
|
| 36 |
+
"outputs": [],
|
| 37 |
+
"source": [
|
| 38 |
+
"text = \"\"\"\n",
|
| 39 |
+
"Over the past decade, astronomers have discovered three mysterious objects traveling through our solar system that originated from beyond it—interstellar visitors named 'Oumuamua, Borisov, and ATLAS. A key question has been: where did these objects come from and when? This research tackles that puzzle by working backward through space and time, using the gravitational pull of our galaxy to trace each object's likely trajectory and determine which stars might have ejected them.\n",
|
| 40 |
+
"\n",
|
| 41 |
+
"The researchers used advanced computer simulations, running 10,000 different possible paths for each object to account for measurement uncertainties. They then employed a statistical framework inspired by Bayesian reasoning—essentially a method for updating beliefs based on evidence—combined with knowledge about how stars of different ages move in our galaxy. By measuring how far each object's orbit takes it above and below the galactic plane, they could estimate how old the star system was that originally launched it. Younger stars stay closer to the galactic plane, while older stars have been \"heated up\" by gravitational interactions over billions of years and venture farther away.\n",
|
| 42 |
+
"\n",
|
| 43 |
+
"The results reveal a clear pattern: 'Oumuamua came from a young star system about 1 billion years old, Borisov from a middle-aged system around 3.8 billion years old, and ATLAS from an ancient system roughly 9.6 billion years old. This research demonstrates a novel technique for investigating interstellar objects and hints at the diverse stellar populations throughout our galaxy that may be flinging objects into interstellar space.\n",
|
| 44 |
+
"\"\"\""
|
| 45 |
+
]
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"cell_type": "code",
|
| 49 |
+
"execution_count": null,
|
| 50 |
"id": "99d19e18",
|
| 51 |
"metadata": {},
|
| 52 |
+
"outputs": [],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
"source": [
|
| 54 |
"from elevenlabs.client import ElevenLabs\n",
|
| 55 |
"from elevenlabs.play import play\n",
|
|
|
|
| 59 |
")\n",
|
| 60 |
"\n",
|
| 61 |
"audio = client.text_to_speech.convert(\n",
|
| 62 |
+
" text=text,\n",
|
| 63 |
" voice_id=\"JBFqnCBsd6RMkjVDRZzb\",\n",
|
| 64 |
" model_id=\"eleven_multilingual_v2\",\n",
|
| 65 |
" output_format=\"mp3_44100_128\",\n",
|
|
|
|
| 70 |
},
|
| 71 |
{
|
| 72 |
"cell_type": "code",
|
| 73 |
+
"execution_count": 6,
|
| 74 |
"id": "ad8c93d3",
|
| 75 |
"metadata": {},
|
| 76 |
+
"outputs": [],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
"source": [
|
| 78 |
+
"play(audio)\n"
|
| 79 |
]
|
| 80 |
}
|
| 81 |
],
|
| 82 |
"metadata": {
|
| 83 |
"kernelspec": {
|
| 84 |
+
"display_name": "science-storyteller",
|
| 85 |
"language": "python",
|
| 86 |
"name": "python3"
|
| 87 |
},
|
tests/test_elevenlabs.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import dotenv
|
| 3 |
+
dotenv.load_dotenv()
|
| 4 |
+
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
|
| 5 |
+
print(f"Eleven Labs API Key: {ELEVENLABS_API_KEY[0:5]}...")
|
| 6 |
+
|
| 7 |
+
from elevenlabs.client import ElevenLabs
|
| 8 |
+
from elevenlabs.play import play
|
| 9 |
+
|
| 10 |
+
text = """
|
| 11 |
+
星际物体银河轨迹研究总结
|
| 12 |
+
研究问题
|
| 13 |
+
本研究针对一个引人入胜的天文谜题:过去十年里发现的三个星际物体(`Oumuamua、Borisov和ATLAS)来自哪里?这些物体来自我们太阳系之外,穿过银河系。科学家们想通过追踪它们在银河系中的运动轨迹,推断出它们的起源和年龄。
|
| 14 |
+
|
| 15 |
+
研究方法
|
| 16 |
+
研究人员采用了一种精密的计算方法。他们对每个物体进行了10,000次轨道模拟,以考虑测量数据中的不确定性。关键创新在于结合贝叶斯统计框架——一种处理概率的数学方法——与银河系恒星形成速率数据。通过分析这些物体在银河系中垂直方向的最大偏离距离,结合考虑不同年代恒星的运动特性差异,他们能够推断出这些物体的起源年代。
|
| 17 |
+
|
| 18 |
+
主要发现
|
| 19 |
+
研究结果显示出清晰的模式:`Oumuamua来自非常年轻的恒星系统(约10亿年),Borisov来自中等年龄的恒星(约38亿年),而ATLAS来自非常古老的银河系厚盘结构(约96亿年)。这一发现意义重大,因为它表明通过测量星际物体的银河轨道特征,科学家们可以推断这些神秘访客的起源时间和源头恒星的年龄——为理解宇宙中物质如何在星系间传播提供了新的洞见。
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
client = ElevenLabs(
|
| 23 |
+
api_key=ELEVENLABS_API_KEY
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
audio = client.text_to_speech.convert(
|
| 27 |
+
text=text,
|
| 28 |
+
#voice_id="JBFqnCBsd6RMkjVDRZzb",
|
| 29 |
+
voice_id="9lHjugDhwqoxA5MhX0az",
|
| 30 |
+
model_id="eleven_multilingual_v2",
|
| 31 |
+
output_format="mp3_44100_128",
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
# play(audio)
|
| 35 |
+
|
| 36 |
+
with open("test_elevenlabs_output_zh.mp3", "wb") as f:
|
| 37 |
+
for chunk in audio:
|
| 38 |
+
f.write(chunk)
|
tests/test_semantic_scholar.ipynb
CHANGED
|
@@ -8,30 +8,6 @@
|
|
| 8 |
"# Test Semantic Scholar API"
|
| 9 |
]
|
| 10 |
},
|
| 11 |
-
{
|
| 12 |
-
"cell_type": "code",
|
| 13 |
-
"execution_count": 1,
|
| 14 |
-
"id": "f26a7c5b",
|
| 15 |
-
"metadata": {},
|
| 16 |
-
"outputs": [],
|
| 17 |
-
"source": [
|
| 18 |
-
"import logging\n",
|
| 19 |
-
"from typing import List, Dict, Any, Optional\n",
|
| 20 |
-
"from mcp import ClientSession, StdioServerParameters\n",
|
| 21 |
-
"from mcp.client.stdio import stdio_client"
|
| 22 |
-
]
|
| 23 |
-
},
|
| 24 |
-
{
|
| 25 |
-
"cell_type": "code",
|
| 26 |
-
"execution_count": 2,
|
| 27 |
-
"id": "34c8f2f1",
|
| 28 |
-
"metadata": {},
|
| 29 |
-
"outputs": [],
|
| 30 |
-
"source": [
|
| 31 |
-
"# Define the logger\n",
|
| 32 |
-
"logger = logging.getLogger(__name__)"
|
| 33 |
-
]
|
| 34 |
-
},
|
| 35 |
{
|
| 36 |
"cell_type": "markdown",
|
| 37 |
"id": "776e804f",
|
|
@@ -51,161 +27,24 @@
|
|
| 51 |
]
|
| 52 |
},
|
| 53 |
{
|
| 54 |
-
"cell_type": "
|
| 55 |
-
"
|
| 56 |
-
"id": "3cff6d52",
|
| 57 |
"metadata": {},
|
| 58 |
-
"outputs": [
|
| 59 |
-
{
|
| 60 |
-
"name": "stdout",
|
| 61 |
-
"output_type": "stream",
|
| 62 |
-
"text": [
|
| 63 |
-
"======================================================================\n",
|
| 64 |
-
"TESTING: Semantic Scholar API (Direct)\n",
|
| 65 |
-
"======================================================================\n",
|
| 66 |
-
"\n",
|
| 67 |
-
"📍 Searching for: 'transformer neural networks'\n",
|
| 68 |
-
" Limit: 3 papers\n",
|
| 69 |
-
"\n",
|
| 70 |
-
"✅ Found 3 papers!\n",
|
| 71 |
-
"\n",
|
| 72 |
-
"======================================================================\n",
|
| 73 |
-
"RESULTS:\n",
|
| 74 |
-
"======================================================================\n",
|
| 75 |
-
"\n",
|
| 76 |
-
"1. Understanding Scaling Laws with Statistical and Approximation Theory for Transformer Neural Networks on Intrinsically Low-dimensional Data\n",
|
| 77 |
-
" Authors: Alex Havrilla, Wenjing Liao\n",
|
| 78 |
-
" Year: 2024\n",
|
| 79 |
-
" Citations: 17\n",
|
| 80 |
-
" URL: https://www.semanticscholar.org/paper/e411a237ca7c6cdb59bb4daab58290c3c5672895\n",
|
| 81 |
-
" Abstract: When training deep neural networks, a model's generalization error is often observed to follow a power scaling law dependent both on the model size and the data size. Perhaps the best known example of...\n",
|
| 82 |
-
"\n",
|
| 83 |
-
"2. Scaling transformer neural networks for skillful and reliable medium-range weather forecasting\n",
|
| 84 |
-
" Authors: Tung Nguyen, Rohan Shah, Hritik Bansal\n",
|
| 85 |
-
" Year: 2023\n",
|
| 86 |
-
" Citations: 100\n",
|
| 87 |
-
" URL: https://www.semanticscholar.org/paper/f9bbc83553ebf8fea9e485ce31b10799d69150e1\n",
|
| 88 |
-
" Abstract: Weather forecasting is a fundamental problem for anticipating and mitigating the impacts of climate change. Recently, data-driven approaches for weather forecasting based on deep learning have shown g...\n",
|
| 89 |
-
"\n",
|
| 90 |
-
"3. Short-term multi-step wind power forecasting based on spatio-temporal correlations and transformer neural networks\n",
|
| 91 |
-
" Authors: Shilin Sun, Yuekai Liu, Qi Li\n",
|
| 92 |
-
" Year: 2023\n",
|
| 93 |
-
" Citations: 137\n",
|
| 94 |
-
" URL: https://www.semanticscholar.org/paper/6d40c57d25095ace2fd165056f5e3578122ddecd\n",
|
| 95 |
-
"\n",
|
| 96 |
-
"======================================================================\n",
|
| 97 |
-
"🎉 Semantic Scholar API is WORKING!\n",
|
| 98 |
-
"We can use this for the project instead of MCP!\n",
|
| 99 |
-
"======================================================================\n",
|
| 100 |
-
"\n",
|
| 101 |
-
"✅ Found 3 papers!\n",
|
| 102 |
-
"\n",
|
| 103 |
-
"======================================================================\n",
|
| 104 |
-
"RESULTS:\n",
|
| 105 |
-
"======================================================================\n",
|
| 106 |
-
"\n",
|
| 107 |
-
"1. Understanding Scaling Laws with Statistical and Approximation Theory for Transformer Neural Networks on Intrinsically Low-dimensional Data\n",
|
| 108 |
-
" Authors: Alex Havrilla, Wenjing Liao\n",
|
| 109 |
-
" Year: 2024\n",
|
| 110 |
-
" Citations: 17\n",
|
| 111 |
-
" URL: https://www.semanticscholar.org/paper/e411a237ca7c6cdb59bb4daab58290c3c5672895\n",
|
| 112 |
-
" Abstract: When training deep neural networks, a model's generalization error is often observed to follow a power scaling law dependent both on the model size and the data size. Perhaps the best known example of...\n",
|
| 113 |
-
"\n",
|
| 114 |
-
"2. Scaling transformer neural networks for skillful and reliable medium-range weather forecasting\n",
|
| 115 |
-
" Authors: Tung Nguyen, Rohan Shah, Hritik Bansal\n",
|
| 116 |
-
" Year: 2023\n",
|
| 117 |
-
" Citations: 100\n",
|
| 118 |
-
" URL: https://www.semanticscholar.org/paper/f9bbc83553ebf8fea9e485ce31b10799d69150e1\n",
|
| 119 |
-
" Abstract: Weather forecasting is a fundamental problem for anticipating and mitigating the impacts of climate change. Recently, data-driven approaches for weather forecasting based on deep learning have shown g...\n",
|
| 120 |
-
"\n",
|
| 121 |
-
"3. Short-term multi-step wind power forecasting based on spatio-temporal correlations and transformer neural networks\n",
|
| 122 |
-
" Authors: Shilin Sun, Yuekai Liu, Qi Li\n",
|
| 123 |
-
" Year: 2023\n",
|
| 124 |
-
" Citations: 137\n",
|
| 125 |
-
" URL: https://www.semanticscholar.org/paper/6d40c57d25095ace2fd165056f5e3578122ddecd\n",
|
| 126 |
-
"\n",
|
| 127 |
-
"======================================================================\n",
|
| 128 |
-
"🎉 Semantic Scholar API is WORKING!\n",
|
| 129 |
-
"We can use this for the project instead of MCP!\n",
|
| 130 |
-
"======================================================================\n"
|
| 131 |
-
]
|
| 132 |
-
}
|
| 133 |
-
],
|
| 134 |
"source": [
|
| 135 |
-
"
|
| 136 |
-
"\n",
|
| 137 |
-
"import requests\n",
|
| 138 |
-
"import json\n",
|
| 139 |
-
"\n",
|
| 140 |
-
"print(\"=\" * 70)\n",
|
| 141 |
-
"print(\"TESTING: Semantic Scholar API (Direct)\")\n",
|
| 142 |
-
"print(\"=\" * 70)\n",
|
| 143 |
-
"\n",
|
| 144 |
-
"# Semantic Scholar API endpoint\n",
|
| 145 |
-
"API_BASE = \"https://api.semanticscholar.org/graph/v1\"\n",
|
| 146 |
-
"\n",
|
| 147 |
-
"def search_papers(query: str, limit: int = 5):\n",
|
| 148 |
-
" \"\"\"\n",
|
| 149 |
-
" Search for papers using Semantic Scholar API\n",
|
| 150 |
-
" \n",
|
| 151 |
-
" Args:\n",
|
| 152 |
-
" query: Search query string\n",
|
| 153 |
-
" limit: Maximum number of results\n",
|
| 154 |
-
" \n",
|
| 155 |
-
" Returns:\n",
|
| 156 |
-
" List of paper data\n",
|
| 157 |
-
" \"\"\"\n",
|
| 158 |
-
" url = f\"{API_BASE}/paper/search\"\n",
|
| 159 |
-
" \n",
|
| 160 |
-
" params = {\n",
|
| 161 |
-
" \"query\": query,\n",
|
| 162 |
-
" \"limit\": limit,\n",
|
| 163 |
-
" \"fields\": \"paperId,title,abstract,authors,year,citationCount,url,publicationDate\"\n",
|
| 164 |
-
" }\n",
|
| 165 |
-
" \n",
|
| 166 |
-
" print(f\"\\n📍 Searching for: '{query}'\")\n",
|
| 167 |
-
" print(f\" Limit: {limit} papers\")\n",
|
| 168 |
-
" \n",
|
| 169 |
-
" try:\n",
|
| 170 |
-
" response = requests.get(url, params=params, timeout=10)\n",
|
| 171 |
-
" response.raise_for_status()\n",
|
| 172 |
-
" \n",
|
| 173 |
-
" data = response.json()\n",
|
| 174 |
-
" papers = data.get(\"data\", [])\n",
|
| 175 |
-
" \n",
|
| 176 |
-
" print(f\"\\n✅ Found {len(papers)} papers!\")\n",
|
| 177 |
-
" return papers\n",
|
| 178 |
-
" \n",
|
| 179 |
-
" except requests.exceptions.RequestException as e:\n",
|
| 180 |
-
" print(f\"\\n❌ API Error: {e}\")\n",
|
| 181 |
-
" return []\n",
|
| 182 |
-
"\n",
|
| 183 |
-
"# Test the API\n",
|
| 184 |
-
"test_query = \"transformer neural networks\"\n",
|
| 185 |
-
"results = search_papers(test_query, limit=3)\n",
|
| 186 |
-
"\n",
|
| 187 |
-
"print(\"\\n\" + \"=\" * 70)\n",
|
| 188 |
-
"print(\"RESULTS:\")\n",
|
| 189 |
-
"print(\"=\" * 70)\n",
|
| 190 |
"\n",
|
| 191 |
-
"
|
| 192 |
-
"
|
| 193 |
-
"
|
| 194 |
-
"
|
| 195 |
-
"
|
| 196 |
-
" print(f\" URL: {paper.get('url', 'N/A')}\")\n",
|
| 197 |
-
" \n",
|
| 198 |
-
" abstract = paper.get('abstract', 'No abstract available')\n",
|
| 199 |
-
" if abstract:\n",
|
| 200 |
-
" print(f\" Abstract: {abstract[:200]}...\")\n",
|
| 201 |
"\n",
|
| 202 |
-
"
|
| 203 |
-
"
|
| 204 |
-
"
|
| 205 |
-
"
|
| 206 |
-
"
|
| 207 |
-
"
|
| 208 |
-
"print(\"=\" * 70)"
|
| 209 |
]
|
| 210 |
},
|
| 211 |
{
|
|
@@ -225,7 +64,7 @@
|
|
| 225 |
},
|
| 226 |
{
|
| 227 |
"cell_type": "code",
|
| 228 |
-
"execution_count":
|
| 229 |
"id": "aa1ad8a3",
|
| 230 |
"metadata": {},
|
| 231 |
"outputs": [
|
|
@@ -245,7 +84,7 @@
|
|
| 245 |
},
|
| 246 |
{
|
| 247 |
"cell_type": "code",
|
| 248 |
-
"execution_count":
|
| 249 |
"id": "fa5a029d",
|
| 250 |
"metadata": {},
|
| 251 |
"outputs": [],
|
|
@@ -259,443 +98,140 @@
|
|
| 259 |
" \"limit\": 3,\n",
|
| 260 |
" \"fields\": \"year,title,abstract\"\n",
|
| 261 |
" },\n",
|
| 262 |
-
" headers = {\"x-api-key\": SEMANTIC_SCHOLAR_API_KEY})
|
| 263 |
-
"\n"
|
| 264 |
]
|
| 265 |
},
|
| 266 |
{
|
| 267 |
"cell_type": "code",
|
| 268 |
-
"execution_count":
|
| 269 |
-
"id": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
"metadata": {},
|
| 271 |
"outputs": [
|
| 272 |
{
|
| 273 |
"data": {
|
| 274 |
"text/plain": [
|
| 275 |
-
"
|
| 276 |
-
" 'offset': 0,\n",
|
| 277 |
-
" 'next': 3,\n",
|
| 278 |
-
" 'data': [{'paperId': '12d84412ea529baa9e6bde720beb3d825c718f27',\n",
|
| 279 |
-
" 'title': \"Galactic Trajectories of Interstellar Objects 1I/'Oumuamua, 2I/Borisov, and 3I/Atlas\",\n",
|
| 280 |
-
" 'year': 2024,\n",
|
| 281 |
-
" 'openAccessPdf': {'url': '',\n",
|
| 282 |
-
" 'status': None,\n",
|
| 283 |
-
" 'license': None,\n",
|
| 284 |
-
" 'disclaimer': 'Notice: Paper or abstract available at https://arxiv.org/abs/2408.02739, which is subject to the license by the author or copyright owner provided with this content. Please go to the source to verify the license and copyright information for your use.'},\n",
|
| 285 |
-
" 'authors': [{'authorId': '2314918962', 'name': 'Shokhruz Kakharov'},\n",
|
| 286 |
-
" {'authorId': '2314918346', 'name': 'Abraham Loeb'}],\n",
|
| 287 |
-
" 'abstract': 'The first interstellar objects, 1I/`Oumuamua, 2I/Borisov and 3I/ATLAS, were discovered over the past decade. We follow the trajectories of known interstellar objects in the gravitational potential of the Milky Way galaxy to constrain their possible origin. We perform Monte Carlo orbital integrations using 10,000 trajectory ensembles per object to properly account for measurement uncertainties in both object velocities and Solar motion parameters. We implement a Bayesian statistical framework that combines a Rayleigh-like likelihood function with star formation rate priors to infer stellar ages from the maximum vertical excursions ($z_{\\\\text{max}}$) of orbital trajectories. The likelihood function incorporates age-dependent velocity dispersions reflecting the thin-thick disk transition and dynamical heating over galactic history. Our Monte Carlo analysis yields median $z_{\\\\text{max}}$ values of 0.016 $\\\\pm$ 0.002 kpc for 1I/`Oumuamua, 0.121 $\\\\pm$ 0.010 kpc for 2I/Borisov, and 0.480 $\\\\pm$ 0.020 kpc for 3I/ATLAS. The Bayesian age inference indicates that 1I/`Oumuamua originated from a young stellar system (1.0 Gyr, 68\\\\% CI: 0.1-4.1 Gyr), 2I/Borisov from an intermediate-age population (3.8 Gyr, 68\\\\% CI: 1.8-5.9 Gyr), and 3I/ATLAS from an old thick-disk source (9.6 Gyr, 68\\\\% CI: 7.8-10.3 Gyr). These results demonstrate clear age discrimination where smaller vertical excursions correspond to younger stellar origins.'},\n",
|
| 288 |
-
" {'paperId': '594246b2c2b2b8a818fa0eeaa90db9c3393f9aea',\n",
|
| 289 |
-
" 'title': 'Hubble Space Telescope Observations of the Interstellar Interloper 3I/ATLAS',\n",
|
| 290 |
-
" 'year': 2025,\n",
|
| 291 |
-
" 'openAccessPdf': {'url': '',\n",
|
| 292 |
-
" 'status': None,\n",
|
| 293 |
-
" 'license': None,\n",
|
| 294 |
-
" 'disclaimer': 'Notice: Paper or abstract available at https://arxiv.org/abs/2508.02934, which is subject to the license by the author or copyright owner provided with this content. Please go to the source to verify the license and copyright information for your use.'},\n",
|
| 295 |
-
" 'authors': [{'authorId': '39511008', 'name': 'D. Jewitt'},\n",
|
| 296 |
-
" {'authorId': '2358904546', 'name': 'Man-To Hui'},\n",
|
| 297 |
-
" {'authorId': '50702037', 'name': 'M. Mutchler'},\n",
|
| 298 |
-
" {'authorId': '2244773753', 'name': 'Yoonyoung Kim'},\n",
|
| 299 |
-
" {'authorId': '2374965494', 'name': 'Jessica Agarwal'}],\n",
|
| 300 |
-
" 'abstract': 'We present high-angular-resolution observations of the third known interstellar interloper, 3I/ATLAS, from the Hubble Space Telescope. The object is clearly active at 3.8 au preperihelion, showing dust emitted from the hot, Sun-facing side of the nucleus and a weak, radiation-pressure-swept tail away from the Sun. We apply a simple model to estimate the mass loss rate in dust as dM/dt ∼ 12 aμ1/2 kg s−1, where aμ is the mean particle size in microns. With 1 ≤ aμ ≤ 100, we infer dM/dt ∼ 12–120 kg s−1. A fit to the surface brightness distribution of the inner coma limits the effective radius of the nucleus to rn ≤ 2.8 km, assuming red geometric albedo 0.04. Conversely, the nucleus cannot be smaller than ∼0.22 km in radius if its coma is supplied by sublimation of carbon monoxide and must be larger if a less volatile molecule drives the mass loss.'},\n",
|
| 301 |
-
" {'paperId': 'ebbb9180df1c969e1ce78cfcd824645d0ff6cb30',\n",
|
| 302 |
-
" 'title': 'Assessing interstellar comet 3I/ATLAS with the 10.4 m Gran Telescopio Canarias and the Two-meter Twin Telescope',\n",
|
| 303 |
-
" 'year': 2025,\n",
|
| 304 |
-
" 'openAccessPdf': {'url': '',\n",
|
| 305 |
-
" 'status': None,\n",
|
| 306 |
-
" 'license': None,\n",
|
| 307 |
-
" 'disclaimer': 'Notice: Paper or abstract available at https://arxiv.org/abs/2507.12922, which is subject to the license by the author or copyright owner provided with this content. Please go to the source to verify the license and copyright information for your use.'},\n",
|
| 308 |
-
" 'authors': [{'authorId': '102971201', 'name': 'R. D. L. F. Marcos'},\n",
|
| 309 |
-
" {'authorId': '2288013864', 'name': 'M. R. Alarcon'},\n",
|
| 310 |
-
" {'authorId': '2258549566', 'name': 'J. Licandro'},\n",
|
| 311 |
-
" {'authorId': '1476099322', 'name': 'M. Serra-Ricart'},\n",
|
| 312 |
-
" {'authorId': '2271762070', 'name': 'J. D. León'},\n",
|
| 313 |
-
" {'authorId': '145059909', 'name': 'C. D. L. F. Marcos'},\n",
|
| 314 |
-
" {'authorId': '2371997184', 'name': 'G. Lombardi'},\n",
|
| 315 |
-
" {'authorId': '2330399384', 'name': 'A. Tejero'},\n",
|
| 316 |
-
" {'authorId': '2319830803', 'name': 'A. Cabrera-Lavers'},\n",
|
| 317 |
-
" {'authorId': '2348543093', 'name': 'S. G. Arencibia'},\n",
|
| 318 |
-
" {'authorId': '2351808571', 'name': 'I. R. Cejudo'}],\n",
|
| 319 |
-
" 'abstract': \"Theories of the formation and evolution of small bodies in planetary systems predict that they may escape into interstellar space at any time, leaked from extrasolar Oort clouds or ejected following close encounters with local planets or their host stars. After just two such interlopers -- 1I/2017 U1 (`Oumuamua) and 2I/Borisov -- had been characterized, more questions had been raised than answered. Assessing the recently discovered interstellar comet 3I/ATLAS will only broaden our understanding of this complex topic. Here, we investigate the spectral, cometary, and rotational properties of 3I/ATLAS as well as its dynamical context. We identified the spectral type of 3I/ATLAS from the visible reflectance spectrum and used photometric observations to derive its level of activity and rotational properties. Observational data were obtained with the OSIRIS camera spectrograph at the 10.4 m Gran Telescopio Canarias and the Two-meter Twin Telescope. We used N-body simulations and statistical analyses of Gaia DR3 data to investigate the origin of 3I/ATLAS and its Galactic background. Interstellar comet 3I/ATLAS has a visible spectrum slightly redder than the ones of D-type asteroids, 1I/'Oumuamua and 2I/Borisov, with a spectral slope of S'=18.3±0.9 %/1000 Å in the 4000--9000 Å range, which is similar to the ones of trans-Neptunian objects and Centaurs. It has a conspicuous coma and its rotation period is 16.79±0.23 h. The heliocentric components of its Galactic velocity are $(U, V, W)=(-51.233±0.006,-19.456±0.004, +18.930_ )$ km s^-1 with a radiant in Sagittarius of $(α, δ)=(295 fdg004 fdg003 fdg0005 fdg0006 $). The analysis of a sample of kinematic analogs of 3I/ATLAS extracted from Gaia DR3 suggests that its parent system is part of the Galactic thin disk and includes a solar-like star with a slightly subsolar metallicity. The results from the physical characterization of 3I/ATLAS further support the idea that extrasolar debris is not too different from the debris found in the Solar System and that it is the result of similar formation processes.\"}]}"
|
| 320 |
]
|
| 321 |
},
|
| 322 |
-
"execution_count":
|
| 323 |
"metadata": {},
|
| 324 |
"output_type": "execute_result"
|
| 325 |
}
|
| 326 |
],
|
| 327 |
"source": [
|
| 328 |
-
"
|
| 329 |
-
|
| 330 |
-
},
|
| 331 |
-
{
|
| 332 |
-
"cell_type": "markdown",
|
| 333 |
-
"id": "cfd53868",
|
| 334 |
-
"metadata": {},
|
| 335 |
-
"source": [
|
| 336 |
-
"## 📚 Learning: API Calls in Python\n",
|
| 337 |
-
"\n",
|
| 338 |
-
"**Why APIs Matter in AI/Python:**\n",
|
| 339 |
-
"- Access to data (research papers, images, text datasets)\n",
|
| 340 |
-
"- Connect to AI services (OpenAI, Anthropic, ElevenLabs)\n",
|
| 341 |
-
"- Integrate external tools (databases, search engines, social media)\n",
|
| 342 |
-
"- Build distributed systems\n",
|
| 343 |
-
"\n",
|
| 344 |
-
"**Key Concepts:**\n",
|
| 345 |
-
"1. **REST APIs** - Most common (GET, POST, PUT, DELETE)\n",
|
| 346 |
-
"2. **HTTP Status Codes** - 200 (OK), 404 (Not Found), 500 (Server Error)\n",
|
| 347 |
-
"3. **Authentication** - API keys, OAuth tokens\n",
|
| 348 |
-
"4. **Rate Limiting** - Prevent abuse, manage costs\n",
|
| 349 |
-
"5. **Error Handling** - Network failures, timeouts, invalid responses"
|
| 350 |
-
]
|
| 351 |
-
},
|
| 352 |
-
{
|
| 353 |
-
"cell_type": "code",
|
| 354 |
-
"execution_count": null,
|
| 355 |
-
"id": "319f6174",
|
| 356 |
-
"metadata": {},
|
| 357 |
-
"outputs": [],
|
| 358 |
-
"source": [
|
| 359 |
-
"# 1. Basic GET Request - The Foundation\n",
|
| 360 |
-
"\n",
|
| 361 |
-
"import requests\n",
|
| 362 |
-
"\n",
|
| 363 |
-
"# Simple GET request\n",
|
| 364 |
-
"print(\"=\" * 70)\n",
|
| 365 |
-
"print(\"1️⃣ BASIC GET REQUEST\")\n",
|
| 366 |
-
"print(\"=\" * 70)\n",
|
| 367 |
-
"\n",
|
| 368 |
-
"url = \"https://api.github.com/users/octocat\"\n",
|
| 369 |
-
"response = requests.get(url)\n",
|
| 370 |
-
"\n",
|
| 371 |
-
"print(f\"Status Code: {response.status_code}\") # 200 means success\n",
|
| 372 |
-
"print(f\"Response Type: {type(response)}\")\n",
|
| 373 |
-
"print(f\"Content Type: {response.headers.get('Content-Type')}\")\n",
|
| 374 |
-
"\n",
|
| 375 |
-
"# Parse JSON response\n",
|
| 376 |
-
"data = response.json()\n",
|
| 377 |
-
"print(f\"\\nUser: {data['login']}\")\n",
|
| 378 |
-
"print(f\"Name: {data['name']}\")\n",
|
| 379 |
-
"print(f\"Public Repos: {data['public_repos']}\")\n",
|
| 380 |
-
"\n",
|
| 381 |
-
"print(\"\\n💡 Key Takeaway: requests.get(url) → response object → .json() to parse\")"
|
| 382 |
]
|
| 383 |
},
|
| 384 |
{
|
| 385 |
"cell_type": "code",
|
| 386 |
-
"execution_count":
|
| 387 |
-
"id": "
|
| 388 |
"metadata": {},
|
| 389 |
-
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
"source": [
|
| 391 |
-
"#
|
| 392 |
-
"\n",
|
| 393 |
-
"print(\"\\n\" + \"=\" * 70)\n",
|
| 394 |
-
"print(\"2️⃣ QUERY PARAMETERS\")\n",
|
| 395 |
-
"print(\"=\" * 70)\n",
|
| 396 |
-
"\n",
|
| 397 |
-
"# Method 1: Manual URL construction (don't do this!)\n",
|
| 398 |
-
"bad_url = \"https://api.github.com/search/repositories?q=python&sort=stars&per_page=3\"\n",
|
| 399 |
"\n",
|
| 400 |
-
"
|
| 401 |
-
"base_url = \"https://api.github.com/search/repositories\"\n",
|
| 402 |
-
"params = {\n",
|
| 403 |
-
" \"q\": \"python machine learning\",\n",
|
| 404 |
-
" \"sort\": \"stars\",\n",
|
| 405 |
-
" \"per_page\": 3\n",
|
| 406 |
-
"}\n",
|
| 407 |
-
"\n",
|
| 408 |
-
"response = requests.get(base_url, params=params)\n",
|
| 409 |
-
"data = response.json()\n",
|
| 410 |
-
"\n",
|
| 411 |
-
"print(f\"Total repos found: {data['total_count']}\")\n",
|
| 412 |
-
"print(f\"\\nTop 3 repos:\")\n",
|
| 413 |
-
"for i, repo in enumerate(data['items'], 1):\n",
|
| 414 |
-
" print(f\"{i}. {repo['name']} - ⭐ {repo['stargazers_count']} stars\")\n",
|
| 415 |
-
"\n",
|
| 416 |
-
"print(\"\\n💡 Key Takeaway: Use params={} dict for clean, safe URL parameters\")"
|
| 417 |
]
|
| 418 |
},
|
| 419 |
{
|
| 420 |
"cell_type": "code",
|
| 421 |
-
"execution_count":
|
| 422 |
-
"id": "
|
| 423 |
"metadata": {},
|
| 424 |
"outputs": [],
|
| 425 |
"source": [
|
| 426 |
-
"
|
| 427 |
-
"\n",
|
| 428 |
-
"print(\"\\n\" + \"=\" * 70)\n",
|
| 429 |
-
"print(\"3️⃣ ERROR HANDLING\")\n",
|
| 430 |
-
"print(\"=\" * 70)\n",
|
| 431 |
-
"\n",
|
| 432 |
-
"def safe_api_call(url, params=None):\n",
|
| 433 |
-
" \"\"\"Robust API call with error handling\"\"\"\n",
|
| 434 |
-
" try:\n",
|
| 435 |
-
" response = requests.get(url, params=params, timeout=5)\n",
|
| 436 |
-
" \n",
|
| 437 |
-
" # Check if request was successful\n",
|
| 438 |
-
" response.raise_for_status() # Raises HTTPError for 4xx/5xx\n",
|
| 439 |
-
" \n",
|
| 440 |
-
" return response.json()\n",
|
| 441 |
-
" \n",
|
| 442 |
-
" except requests.exceptions.Timeout:\n",
|
| 443 |
-
" print(\"❌ Request timed out\")\n",
|
| 444 |
-
" return None\n",
|
| 445 |
-
" \n",
|
| 446 |
-
" except requests.exceptions.ConnectionError:\n",
|
| 447 |
-
" print(\"❌ Connection failed - check your internet\")\n",
|
| 448 |
-
" return None\n",
|
| 449 |
-
" \n",
|
| 450 |
-
" except requests.exceptions.HTTPError as e:\n",
|
| 451 |
-
" print(f\"❌ HTTP Error: {e.response.status_code}\")\n",
|
| 452 |
-
" return None\n",
|
| 453 |
-
" \n",
|
| 454 |
-
" except requests.exceptions.RequestException as e:\n",
|
| 455 |
-
" print(f\"❌ General error: {e}\")\n",
|
| 456 |
-
" return None\n",
|
| 457 |
-
" \n",
|
| 458 |
-
" except ValueError:\n",
|
| 459 |
-
" print(\"❌ Invalid JSON response\")\n",
|
| 460 |
-
" return None\n",
|
| 461 |
-
"\n",
|
| 462 |
-
"# Test with valid API\n",
|
| 463 |
-
"print(\"Test 1: Valid API\")\n",
|
| 464 |
-
"data = safe_api_call(\"https://api.github.com/users/octocat\")\n",
|
| 465 |
-
"if data:\n",
|
| 466 |
-
" print(f\"✅ Success: {data['login']}\")\n",
|
| 467 |
-
"\n",
|
| 468 |
-
"# Test with invalid endpoint (404)\n",
|
| 469 |
-
"print(\"\\nTest 2: Invalid endpoint\")\n",
|
| 470 |
-
"data = safe_api_call(\"https://api.github.com/users/this-user-definitely-does-not-exist-12345\")\n",
|
| 471 |
-
"\n",
|
| 472 |
-
"print(\"\\n💡 Key Takeaway: ALWAYS handle errors - networks fail, APIs change, limits hit\")"
|
| 473 |
]
|
| 474 |
},
|
| 475 |
{
|
| 476 |
"cell_type": "code",
|
| 477 |
-
"execution_count":
|
| 478 |
-
"id": "
|
| 479 |
"metadata": {},
|
| 480 |
-
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
"source": [
|
| 482 |
-
"
|
| 483 |
-
"\n",
|
| 484 |
-
"print(\"\\n\" + \"=\" * 70)\n",
|
| 485 |
-
"print(\"4️⃣ HEADERS & AUTHENTICATION\")\n",
|
| 486 |
-
"print(\"=\" * 70)\n",
|
| 487 |
-
"\n",
|
| 488 |
-
"# Example 1: Custom headers\n",
|
| 489 |
-
"headers = {\n",
|
| 490 |
-
" \"User-Agent\": \"MyApp/1.0\",\n",
|
| 491 |
-
" \"Accept\": \"application/json\"\n",
|
| 492 |
-
"}\n",
|
| 493 |
-
"\n",
|
| 494 |
-
"response = requests.get(\"https://api.github.com/users/octocat\", headers=headers)\n",
|
| 495 |
-
"print(f\"✅ Request with custom headers: {response.status_code}\")\n",
|
| 496 |
-
"\n",
|
| 497 |
-
"# Example 2: API Key authentication (common pattern)\n",
|
| 498 |
-
"# DON'T hardcode keys! Use environment variables:\n",
|
| 499 |
-
"# api_key = os.getenv(\"API_KEY\")\n",
|
| 500 |
-
"\n",
|
| 501 |
-
"# Simulated example (won't work without real key)\n",
|
| 502 |
-
"fake_api_key = \"sk-1234567890abcdef\"\n",
|
| 503 |
-
"\n",
|
| 504 |
-
"# Pattern 1: Header-based auth (most common for AI APIs)\n",
|
| 505 |
-
"headers_with_auth = {\n",
|
| 506 |
-
" \"Authorization\": f\"Bearer {fake_api_key}\",\n",
|
| 507 |
-
" \"Content-Type\": \"application/json\"\n",
|
| 508 |
-
"}\n",
|
| 509 |
-
"\n",
|
| 510 |
-
"# Pattern 2: Query parameter auth (some APIs)\n",
|
| 511 |
-
"params_with_auth = {\n",
|
| 512 |
-
" \"api_key\": fake_api_key,\n",
|
| 513 |
-
" \"query\": \"something\"\n",
|
| 514 |
-
"}\n",
|
| 515 |
-
"\n",
|
| 516 |
-
"print(\"\\n🔑 Authentication Patterns:\")\n",
|
| 517 |
-
"print(\"1. Bearer Token: Authorization: Bearer <token>\")\n",
|
| 518 |
-
"print(\"2. API Key Header: X-API-Key: <key>\")\n",
|
| 519 |
-
"print(\"3. Query Parameter: ?api_key=<key>\")\n",
|
| 520 |
-
"print(\"4. Basic Auth: requests.get(url, auth=('user', 'pass'))\")\n",
|
| 521 |
-
"\n",
|
| 522 |
-
"print(\"\\n💡 Key Takeaway: Use os.getenv() for API keys, never hardcode them!\")"
|
| 523 |
]
|
| 524 |
},
|
| 525 |
{
|
| 526 |
"cell_type": "code",
|
| 527 |
-
"execution_count":
|
| 528 |
-
"id": "
|
| 529 |
"metadata": {},
|
| 530 |
-
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 531 |
"source": [
|
| 532 |
-
"#
|
| 533 |
-
"\n",
|
| 534 |
-
"print(\"\\n\" + \"=\" * 70)\n",
|
| 535 |
-
"print(\"5️⃣ POST REQUESTS\")\n",
|
| 536 |
-
"print(\"=\" * 70)\n",
|
| 537 |
-
"\n",
|
| 538 |
-
"# POST sends data TO the server (vs GET which retrieves)\n",
|
| 539 |
-
"\n",
|
| 540 |
-
"# Example: Creating data (simulated with httpbin.org test API)\n",
|
| 541 |
-
"url = \"https://httpbin.org/post\"\n",
|
| 542 |
-
"\n",
|
| 543 |
-
"# Method 1: JSON data (most common for modern APIs)\n",
|
| 544 |
-
"json_data = {\n",
|
| 545 |
-
" \"name\": \"AI Research Paper\",\n",
|
| 546 |
-
" \"topic\": \"transformer models\",\n",
|
| 547 |
-
" \"year\": 2025\n",
|
| 548 |
-
"}\n",
|
| 549 |
-
"\n",
|
| 550 |
-
"response = requests.post(url, json=json_data)\n",
|
| 551 |
-
"result = response.json()\n",
|
| 552 |
-
"\n",
|
| 553 |
-
"print(\"Sent data:\")\n",
|
| 554 |
-
"print(json_data)\n",
|
| 555 |
-
"print(f\"\\nServer received:\")\n",
|
| 556 |
-
"print(result['json'])\n",
|
| 557 |
-
"\n",
|
| 558 |
-
"# Method 2: Form data (older APIs, file uploads)\n",
|
| 559 |
-
"form_data = {\n",
|
| 560 |
-
" \"username\": \"researcher\",\n",
|
| 561 |
-
" \"email\": \"test@example.com\"\n",
|
| 562 |
-
"}\n",
|
| 563 |
-
"\n",
|
| 564 |
-
"response = requests.post(url, data=form_data)\n",
|
| 565 |
-
"print(f\"\\n✅ Form POST status: {response.status_code}\")\n",
|
| 566 |
"\n",
|
| 567 |
-
"
|
| 568 |
-
"
|
| 569 |
-
"
|
| 570 |
-
"print(\" - files={'file': open('f.txt', 'rb')} for uploads\")"
|
| 571 |
]
|
| 572 |
},
|
| 573 |
{
|
| 574 |
"cell_type": "code",
|
| 575 |
-
"execution_count":
|
| 576 |
-
"id": "
|
| 577 |
"metadata": {},
|
| 578 |
"outputs": [],
|
| 579 |
"source": [
|
| 580 |
-
"#
|
| 581 |
-
"\n",
|
| 582 |
-
"
|
| 583 |
-
"print(\"6️⃣ REAL-WORLD AI API PATTERN\")\n",
|
| 584 |
-
"print(\"=\" * 70)\n",
|
| 585 |
-
"\n",
|
| 586 |
-
"import os\n",
|
| 587 |
-
"import time\n",
|
| 588 |
-
"\n",
|
| 589 |
-
"class ResearchAPIClient:\n",
|
| 590 |
-
" \"\"\"\n",
|
| 591 |
-
" Template for building API clients\n",
|
| 592 |
-
" Common pattern used in production AI applications\n",
|
| 593 |
-
" \"\"\"\n",
|
| 594 |
-
" \n",
|
| 595 |
-
" def __init__(self, api_key: str = None, base_url: str = None):\n",
|
| 596 |
-
" self.api_key = api_key or os.getenv(\"RESEARCH_API_KEY\")\n",
|
| 597 |
-
" self.base_url = base_url or \"https://api.semanticscholar.org/graph/v1\"\n",
|
| 598 |
-
" self.session = requests.Session() # Reuse connections\n",
|
| 599 |
-
" \n",
|
| 600 |
-
" def _make_request(self, endpoint: str, params: dict = None, max_retries: int = 3):\n",
|
| 601 |
-
" \"\"\"\n",
|
| 602 |
-
" Internal method to handle all API calls\n",
|
| 603 |
-
" Implements retry logic, rate limiting, error handling\n",
|
| 604 |
-
" \"\"\"\n",
|
| 605 |
-
" url = f\"{self.base_url}/{endpoint}\"\n",
|
| 606 |
-
" \n",
|
| 607 |
-
" for attempt in range(max_retries):\n",
|
| 608 |
-
" try:\n",
|
| 609 |
-
" response = self.session.get(url, params=params, timeout=10)\n",
|
| 610 |
-
" \n",
|
| 611 |
-
" if response.status_code == 429: # Rate limit\n",
|
| 612 |
-
" wait_time = 2 ** attempt # Exponential backoff\n",
|
| 613 |
-
" print(f\"⏳ Rate limited, waiting {wait_time}s...\")\n",
|
| 614 |
-
" time.sleep(wait_time)\n",
|
| 615 |
-
" continue\n",
|
| 616 |
-
" \n",
|
| 617 |
-
" response.raise_for_status()\n",
|
| 618 |
-
" return response.json()\n",
|
| 619 |
-
" \n",
|
| 620 |
-
" except requests.exceptions.RequestException as e:\n",
|
| 621 |
-
" if attempt == max_retries - 1:\n",
|
| 622 |
-
" print(f\"❌ Failed after {max_retries} attempts: {e}\")\n",
|
| 623 |
-
" return None\n",
|
| 624 |
-
" print(f\"⚠️ Attempt {attempt + 1} failed, retrying...\")\n",
|
| 625 |
-
" time.sleep(1)\n",
|
| 626 |
-
" \n",
|
| 627 |
-
" return None\n",
|
| 628 |
-
" \n",
|
| 629 |
-
" def search_papers(self, query: str, limit: int = 5):\n",
|
| 630 |
-
" \"\"\"Public method - clean interface for users\"\"\"\n",
|
| 631 |
-
" params = {\n",
|
| 632 |
-
" \"query\": query,\n",
|
| 633 |
-
" \"limit\": limit,\n",
|
| 634 |
-
" \"fields\": \"paperId,title,abstract,authors,year,citationCount\"\n",
|
| 635 |
-
" }\n",
|
| 636 |
-
" return self._make_request(\"paper/search\", params)\n",
|
| 637 |
-
"\n",
|
| 638 |
-
"# Usage\n",
|
| 639 |
-
"client = ResearchAPIClient()\n",
|
| 640 |
-
"results = client.search_papers(\"deep learning\", limit=2)\n",
|
| 641 |
-
"\n",
|
| 642 |
-
"if results and 'data' in results:\n",
|
| 643 |
-
" print(f\"✅ Found {len(results['data'])} papers\")\n",
|
| 644 |
-
" for paper in results['data']:\n",
|
| 645 |
-
" print(f\" - {paper.get('title', 'No title')}\")\n",
|
| 646 |
-
"\n",
|
| 647 |
-
"print(\"\\n💡 Key Takeaway: Build reusable client classes with:\")\n",
|
| 648 |
-
"print(\" - Error handling\")\n",
|
| 649 |
-
"print(\" - Retry logic\")\n",
|
| 650 |
-
"print(\" - Rate limit handling\")\n",
|
| 651 |
-
"print(\" - Clean public interface\")"
|
| 652 |
-
]
|
| 653 |
-
},
|
| 654 |
-
{
|
| 655 |
-
"cell_type": "markdown",
|
| 656 |
-
"id": "2b8c94ba",
|
| 657 |
-
"metadata": {},
|
| 658 |
-
"source": [
|
| 659 |
-
"## 📖 Resources for Learning More\n",
|
| 660 |
-
"\n",
|
| 661 |
-
"### Essential Documentation\n",
|
| 662 |
-
"- **requests library**: https://requests.readthedocs.io/\n",
|
| 663 |
-
"- **HTTP methods**: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\n",
|
| 664 |
-
"- **Status codes**: https://httpstatuses.com/\n",
|
| 665 |
-
"\n",
|
| 666 |
-
"### Practice APIs (No auth required)\n",
|
| 667 |
-
"- **JSONPlaceholder**: https://jsonplaceholder.typicode.com/ (Fake REST API for testing)\n",
|
| 668 |
-
"- **httpbin**: https://httpbin.org/ (HTTP request & response testing)\n",
|
| 669 |
-
"- **GitHub API**: https://api.github.com/ (Real API with generous limits)\n",
|
| 670 |
-
"- **Pokemon API**: https://pokeapi.co/ (Fun data to practice with)\n",
|
| 671 |
-
"\n",
|
| 672 |
-
"### AI/Research APIs You'll Use\n",
|
| 673 |
-
"- **Semantic Scholar**: https://api.semanticscholar.org/\n",
|
| 674 |
-
"- **arXiv**: https://arxiv.org/help/api/\n",
|
| 675 |
-
"- **OpenAI**: https://platform.openai.com/docs/api-reference\n",
|
| 676 |
-
"- **ElevenLabs**: https://elevenlabs.io/docs/api-reference\n",
|
| 677 |
-
"\n",
|
| 678 |
-
"### Next Steps\n",
|
| 679 |
-
"1. Run all the cells above to see API calls in action\n",
|
| 680 |
-
"2. Modify the queries and parameters to experiment\n",
|
| 681 |
-
"3. Try calling a different API (pick one from practice list)\n",
|
| 682 |
-
"4. Build a simple wrapper for an API you're interested in\n",
|
| 683 |
-
"\n",
|
| 684 |
-
"**Pro tip**: Use `response.text` to see raw response when debugging!"
|
| 685 |
]
|
| 686 |
-
},
|
| 687 |
-
{
|
| 688 |
-
"cell_type": "code",
|
| 689 |
-
"execution_count": null,
|
| 690 |
-
"id": "bd08fc07",
|
| 691 |
-
"metadata": {},
|
| 692 |
-
"outputs": [],
|
| 693 |
-
"source": []
|
| 694 |
}
|
| 695 |
],
|
| 696 |
"metadata": {
|
| 697 |
"kernelspec": {
|
| 698 |
-
"display_name": "
|
| 699 |
"language": "python",
|
| 700 |
"name": "python3"
|
| 701 |
},
|
|
|
|
| 8 |
"# Test Semantic Scholar API"
|
| 9 |
]
|
| 10 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
{
|
| 12 |
"cell_type": "markdown",
|
| 13 |
"id": "776e804f",
|
|
|
|
| 27 |
]
|
| 28 |
},
|
| 29 |
{
|
| 30 |
+
"cell_type": "markdown",
|
| 31 |
+
"id": "cfd53868",
|
|
|
|
| 32 |
"metadata": {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
"source": [
|
| 34 |
+
"## 📚 Learning: API Calls in Python\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
"\n",
|
| 36 |
+
"**Why APIs Matter in AI/Python:**\n",
|
| 37 |
+
"- Access to data (research papers, images, text datasets)\n",
|
| 38 |
+
"- Connect to AI services (OpenAI, Anthropic, ElevenLabs)\n",
|
| 39 |
+
"- Integrate external tools (databases, search engines, social media)\n",
|
| 40 |
+
"- Build distributed systems\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
"\n",
|
| 42 |
+
"**Key Concepts:**\n",
|
| 43 |
+
"1. **REST APIs** - Most common (GET, POST, PUT, DELETE)\n",
|
| 44 |
+
"2. **HTTP Status Codes** - 200 (OK), 404 (Not Found), 500 (Server Error)\n",
|
| 45 |
+
"3. **Authentication** - API keys, OAuth tokens\n",
|
| 46 |
+
"4. **Rate Limiting** - Prevent abuse, manage costs\n",
|
| 47 |
+
"5. **Error Handling** - Network failures, timeouts, invalid responses"
|
|
|
|
| 48 |
]
|
| 49 |
},
|
| 50 |
{
|
|
|
|
| 64 |
},
|
| 65 |
{
|
| 66 |
"cell_type": "code",
|
| 67 |
+
"execution_count": 1,
|
| 68 |
"id": "aa1ad8a3",
|
| 69 |
"metadata": {},
|
| 70 |
"outputs": [
|
|
|
|
| 84 |
},
|
| 85 |
{
|
| 86 |
"cell_type": "code",
|
| 87 |
+
"execution_count": 2,
|
| 88 |
"id": "fa5a029d",
|
| 89 |
"metadata": {},
|
| 90 |
"outputs": [],
|
|
|
|
| 98 |
" \"limit\": 3,\n",
|
| 99 |
" \"fields\": \"year,title,abstract\"\n",
|
| 100 |
" },\n",
|
| 101 |
+
" headers = {\"x-api-key\": SEMANTIC_SCHOLAR_API_KEY})"
|
|
|
|
| 102 |
]
|
| 103 |
},
|
| 104 |
{
|
| 105 |
"cell_type": "code",
|
| 106 |
+
"execution_count": 3,
|
| 107 |
+
"id": "8e3c049b",
|
| 108 |
+
"metadata": {},
|
| 109 |
+
"outputs": [],
|
| 110 |
+
"source": [
|
| 111 |
+
"# The response can be converted to a dictionary via the json() method\n",
|
| 112 |
+
"r_dict = r.json()"
|
| 113 |
+
]
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"cell_type": "code",
|
| 117 |
+
"execution_count": 4,
|
| 118 |
+
"id": "235f06eb",
|
| 119 |
"metadata": {},
|
| 120 |
"outputs": [
|
| 121 |
{
|
| 122 |
"data": {
|
| 123 |
"text/plain": [
|
| 124 |
+
"dict_keys(['total', 'offset', 'next', 'data'])"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
]
|
| 126 |
},
|
| 127 |
+
"execution_count": 4,
|
| 128 |
"metadata": {},
|
| 129 |
"output_type": "execute_result"
|
| 130 |
}
|
| 131 |
],
|
| 132 |
"source": [
|
| 133 |
+
"# Check all keys in the dictionary\n",
|
| 134 |
+
"r_dict.keys()"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
]
|
| 136 |
},
|
| 137 |
{
|
| 138 |
"cell_type": "code",
|
| 139 |
+
"execution_count": 5,
|
| 140 |
+
"id": "8d5c93e6",
|
| 141 |
"metadata": {},
|
| 142 |
+
"outputs": [
|
| 143 |
+
{
|
| 144 |
+
"data": {
|
| 145 |
+
"text/plain": [
|
| 146 |
+
"[\"Galactic Trajectories of Interstellar Objects 1I/'Oumuamua, 2I/Borisov, and 3I/Atlas\",\n",
|
| 147 |
+
" 'Assessing interstellar comet 3I/ATLAS with the 10.4 m Gran Telescopio Canarias and the Two-meter Twin Telescope',\n",
|
| 148 |
+
" 'Hubble Space Telescope Observations of the Interstellar Interloper 3I/ATLAS']"
|
| 149 |
+
]
|
| 150 |
+
},
|
| 151 |
+
"execution_count": 5,
|
| 152 |
+
"metadata": {},
|
| 153 |
+
"output_type": "execute_result"
|
| 154 |
+
}
|
| 155 |
+
],
|
| 156 |
"source": [
|
| 157 |
+
"#r.json()[\"data\"]\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
"\n",
|
| 159 |
+
"[paper[\"title\"] for paper in r.json()[\"data\"]]\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
]
|
| 161 |
},
|
| 162 |
{
|
| 163 |
"cell_type": "code",
|
| 164 |
+
"execution_count": 6,
|
| 165 |
+
"id": "018cb4e8",
|
| 166 |
"metadata": {},
|
| 167 |
"outputs": [],
|
| 168 |
"source": [
|
| 169 |
+
"papers = r_dict.get(\"data\", []) # Default to empty list if key missing"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
]
|
| 171 |
},
|
| 172 |
{
|
| 173 |
"cell_type": "code",
|
| 174 |
+
"execution_count": 7,
|
| 175 |
+
"id": "d782f51b",
|
| 176 |
"metadata": {},
|
| 177 |
+
"outputs": [
|
| 178 |
+
{
|
| 179 |
+
"data": {
|
| 180 |
+
"text/plain": [
|
| 181 |
+
"dict_keys(['paperId', 'title', 'year', 'openAccessPdf', 'authors', 'abstract'])"
|
| 182 |
+
]
|
| 183 |
+
},
|
| 184 |
+
"execution_count": 7,
|
| 185 |
+
"metadata": {},
|
| 186 |
+
"output_type": "execute_result"
|
| 187 |
+
}
|
| 188 |
+
],
|
| 189 |
"source": [
|
| 190 |
+
"papers[0].keys()"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
]
|
| 192 |
},
|
| 193 |
{
|
| 194 |
"cell_type": "code",
|
| 195 |
+
"execution_count": 12,
|
| 196 |
+
"id": "d5744f05",
|
| 197 |
"metadata": {},
|
| 198 |
+
"outputs": [
|
| 199 |
+
{
|
| 200 |
+
"data": {
|
| 201 |
+
"text/plain": [
|
| 202 |
+
"'{\\n \"title\": \"Galactic Trajectories of Interstellar Objects 1I/\\'Oumuamua, 2I/Borisov, and 3I/Atlas\",\\n \"abstract\": \"The first interstellar objects, 1I/`Oumuamua, 2I/Borisov and 3I/ATLAS, were discovered over the past decade. We follow the trajectories of known interstellar objects in the gravitational potential of the Milky Way galaxy to constrain their possible origin. We perform Monte Carlo orbital integrations using 10,000 trajectory ensembles per object to properly account for measurement uncertainties in both object velocities and Solar motion parameters. We implement a Bayesian statistical framework that combines a Rayleigh-like likelihood function with star formation rate priors to infer stellar ages from the maximum vertical excursions ($z_{\\\\\\\\text{max}}$) of orbital trajectories. The likelihood function incorporates age-dependent velocity dispersions reflecting the thin-thick disk transition and dynamical heating over galactic history. Our Monte Carlo analysis yields median $z_{\\\\\\\\text{max}}$ values of 0.016 $\\\\\\\\pm$ 0.002 kpc for 1I/`Oumuamua, 0.121 $\\\\\\\\pm$ 0.010 kpc for 2I/Borisov, and 0.480 $\\\\\\\\pm$ 0.020 kpc for 3I/ATLAS. The Bayesian age inference indicates that 1I/`Oumuamua originated from a young stellar system (1.0 Gyr, 68\\\\\\\\% CI: 0.1-4.1 Gyr), 2I/Borisov from an intermediate-age population (3.8 Gyr, 68\\\\\\\\% CI: 1.8-5.9 Gyr), and 3I/ATLAS from an old thick-disk source (9.6 Gyr, 68\\\\\\\\% CI: 7.8-10.3 Gyr). These results demonstrate clear age discrimination where smaller vertical excursions correspond to younger stellar origins.\",\\n \"year\": 2024\\n}'"
|
| 203 |
+
]
|
| 204 |
+
},
|
| 205 |
+
"execution_count": 12,
|
| 206 |
+
"metadata": {},
|
| 207 |
+
"output_type": "execute_result"
|
| 208 |
+
}
|
| 209 |
+
],
|
| 210 |
"source": [
|
| 211 |
+
"# Convert to JSON\n",
|
| 212 |
+
"import json\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
"\n",
|
| 214 |
+
"paper_summary = {k: papers[0].get(k) for k in [\"title\", \"abstract\", \"year\"]}\n",
|
| 215 |
+
"paper_json = json.dumps(paper_summary, ensure_ascii=False, indent=2)\n",
|
| 216 |
+
"paper_json"
|
|
|
|
| 217 |
]
|
| 218 |
},
|
| 219 |
{
|
| 220 |
"cell_type": "code",
|
| 221 |
+
"execution_count": 13,
|
| 222 |
+
"id": "bd08fc07",
|
| 223 |
"metadata": {},
|
| 224 |
"outputs": [],
|
| 225 |
"source": [
|
| 226 |
+
"# save the text to external file for later use\n",
|
| 227 |
+
"with open(\"example_paper.json\", \"w\") as f:\n",
|
| 228 |
+
" f.write(paper_json)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
}
|
| 231 |
],
|
| 232 |
"metadata": {
|
| 233 |
"kernelspec": {
|
| 234 |
+
"display_name": "science-storyteller",
|
| 235 |
"language": "python",
|
| 236 |
"name": "python3"
|
| 237 |
},
|