Tom Skillman commited on
Commit
c46199b
1 Parent(s): f2bb4ff

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +214 -0
app.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from PIL import Image, ImageDraw, ImageFont
3
+ import io
4
+ import base64
5
+ import requests
6
+ import json
7
+ import threading
8
+ import uuid
9
+ import os
10
+ from datetime import datetime
11
+ import urllib.parse
12
+
13
+
14
+ openai_key = "sk-proj-HmBsYhzg5xvirTFW4HS2T3BlbkFJWf90z4T9oXhMgepP3LQL"
15
+
16
+ user_prompt_examples =[
17
+ "Find me the stars in the hayedes cluster.",
18
+ "Find me the stars in the orion cluster.",
19
+ "Find me the stars in the andromeda cluster.",
20
+ "Find me the stars in the milky way.",
21
+ "Find me the stars in the virgo cluster.",
22
+ "Find me the stars in the bootes cluster.",
23
+ "Find me the stars in the perseus cluster.",
24
+ "Find me the stars in the hydra cluster.",
25
+ "Find me the stars in the Pleiades cluster.",
26
+ "Retrieve stars within 50 light-years of Earth.",
27
+ "List all stars in the Orion Nebula.",
28
+ "Get data on stars with a radial velocity greater than 100 km/s.",
29
+ "Fetch all known white dwarfs in the Sirius star system.",
30
+ "Identify stars in the globular cluster Omega Centauri.",
31
+ "Display stars from the Andromeda Galaxy that are visible from Earth.",
32
+ "Find stars in the Scorpius constellation with a magnitude brighter than 5.",
33
+ "Search for stars with high proper motion in the Ursa Major group."
34
+ ]
35
+
36
+ def talk_to_llm(user_prompt):
37
+ headers = {
38
+ "Content-Type": "application/json",
39
+ "Authorization": f"Bearer {openai_key}"
40
+ }
41
+
42
+ prompt_text = f'''
43
+ As StarGateVR, your role is specialized in customizing ADQL (Astronomical Data Query Language) queries for astronomers. Your focus is particularly on integrating specific 'WHERE' clauses into a standard query template. We will put your WHERE clause into the completed query template.
44
+
45
+ The query includes essential fields like source_id, positional data (RA, DEC), motion data (pmra, pmdec), light parameters, and placeholders for additional parameters.
46
+
47
+ Customizing 'WHERE' Clause: Your primary task is to adapt the 'WHERE' clause to fit the user's specific astronomical requirements. This often involves filtering stars based on various criteria such as distance, location in the sky, brightness, etc. Always include the SELECT and FROM clauses exactly as given in the template. Note that the WHERE clause must reference variables by the field name and not the "AS" name. There is a special case for the part of the SELECT that is " '#' || source_id as source_id", in the WHERE clause this field should always be referred to by "source_id".
48
+
49
+ Here is an example of the WHERE clause:
50
+
51
+ ```
52
+ WHERE (parallax >= 11.11 AND parallax_over_error>=20 AND
53
+ astrometric_excess_noise<=2)
54
+ ```
55
+
56
+ Bounds on Parallax: Always include bounds on parallax in the 'WHERE' clause. This is important as it helps in retrieving stars within a specified 3D region of space.
57
+
58
+ The json structure to return is
59
+ {{
60
+ "reasoning": "<Think through what the user is asking for, and what you know about the GAIA DB and astrsonomy to create their request.>",
61
+ "where_clause": "<a properly formatted ADQL query that will return the stars the user is asking for>"
62
+ }}
63
+
64
+ The users prompt is "{user_prompt}"
65
+ '''
66
+
67
+ data = {
68
+ "model": "gpt-4-turbo",
69
+ "response_format": { "type": "json_object" },
70
+ "messages": [
71
+ {"role": "system", "content": prompt_text},
72
+ ],
73
+ "temperature": .6
74
+ }
75
+
76
+ print ("PROMPT TEXT:\n")
77
+ print (prompt_text)
78
+ response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)
79
+ response_json = response.json()
80
+ print(response_json)
81
+ output_json = json.loads(response_json['choices'][0]['message']['content'])
82
+
83
+ try:
84
+ where_clause = output_json['where_clause']
85
+ reasoning = output_json['reasoning']
86
+ print(f"dialog: {reasoning}")
87
+ print(f"query: {where_clause}")
88
+ # Update theme on the server
89
+ return reasoning, where_clause
90
+ except KeyError as e:
91
+ print(f"Key error: {e}")
92
+ return "Failed to generate query."
93
+ except json.JSONDecodeError:
94
+ print("JSON decoding failed")
95
+ return "Invalid response query."
96
+
97
+ def complete_query(partial_query):
98
+ query_template = f'''
99
+ SELECT TOP 300000
100
+ -- IMPORTANT NOTE: Parameters that are in units of Magnitude must have an "as" name that ends in "_mag"
101
+ --Required parameters
102
+ -- ID - force a leading hash symbol to stop Excel from reading the ID number as a float
103
+ '#' || source_id as source_id,
104
+ -- Measured Position
105
+ ra,
106
+ dec,
107
+ (1 / parallax)*1000 as dist,
108
+ -- Measured Motion
109
+ pmra,
110
+ pmdec,
111
+ radial_velocity as rv,
112
+ --Key source light params for HR diagram
113
+ phot_g_mean_mag,
114
+ bp_rp as bp_rp_mag,
115
+ --Placeholders to be filled in by StarGateVR
116
+ 0 as l,
117
+ 0 as b,
118
+ 0 as X,
119
+ 0 as Y,
120
+ 0 as Z,
121
+ 0 as U,
122
+ 0 as V,
123
+ 0 as W,
124
+ 0 as abs_mag,
125
+ 0 as zero,
126
+ 1 as one,
127
+ --Optional plot parameters (you can add anything you want here, just give good unique "as" names - it will show up in the .cvs and hence in StarGate
128
+ phot_rp_mean_mag,
129
+ phot_bp_mean_mag,
130
+ g_rp as g_rp_mag,
131
+ bp_g as bp_g_mag,
132
+ radial_velocity_error as rv_error,
133
+ parallax_error,
134
+
135
+ -- Note: No comma after this last SELECT item
136
+ parallax_over_error
137
+ -- Use DR3
138
+ FROM gaiadr3.gaia_source
139
+ {partial_query}
140
+ '''
141
+
142
+ print ("completed query")
143
+ print (query_template)
144
+ print (" ")
145
+
146
+ return query_template
147
+
148
+ def download_url_from_query(query, user_prompt):
149
+ # Create the TAP URL
150
+ tap_url = "https://gea.esac.esa.int/tap-server/tap/sync?REQUEST=doQuery&LANG=ADQL&FORMAT=csv&QUERY="
151
+ query = urllib.parse.quote_plus(query)
152
+ tap_url = tap_url + query
153
+ print ("downloading from tap")
154
+ filename = user_prompt.replace(' ', '_').replace('.', '') + ".csv"
155
+ print (filename)
156
+ download_from_tap(tap_url, filename)
157
+
158
+ def create_markdown_url_from_query(query):
159
+ # Create the TAP URL
160
+ tap_url = "https://gea.esac.esa.int/tap-server/tap/sync?REQUEST=doQuery&LANG=ADQL&FORMAT=csv&QUERY="
161
+ query = urllib.parse.quote_plus(query)
162
+ tap_url = tap_url + query
163
+ print (tap_url)
164
+ download_from_tap(tap_url, "output_file.csv")
165
+ markdown_link = download_data(tap_url)
166
+ return markdown_link
167
+
168
+ def download_from_tap(url, output_path):
169
+ try:
170
+ response = requests.get(url)
171
+ response.raise_for_status() # Raises an HTTPError for bad responses (4xx, 5xx)
172
+ with open(output_path, 'wb') as f:
173
+ f.write(response.content)
174
+ print(f"Data successfully downloaded to {output_path}.")
175
+ except requests.exceptions.HTTPError as err:
176
+ print(f"HTTP error occurred: {err}") # Handle specific HTTP errors
177
+ except Exception as err:
178
+ print(f"An error occurred: {err}") # Handle other possible errors
179
+
180
+ def download_data(tap_url):
181
+ return f"[Download Data]({tap_url})"
182
+
183
+ # Main function to process all queries
184
+ def process_queries():
185
+ results = {}
186
+ for prompt in user_prompt_examples:
187
+ print (f"Processing prompt: {prompt}")
188
+ reasoning, where_clause = talk_to_llm(prompt)
189
+ query = complete_query(where_clause)
190
+ download_url_from_query(query, prompt)
191
+ return results
192
+
193
+ with gr.Blocks() as demo:
194
+ with gr.Row():
195
+ user_prompt = gr.Textbox(label="Enter your query for the LLM", value="Find me the stars in the hayedes cluster.")
196
+ submit_btn = gr.Button("Ask LLM")
197
+ reasoning_output = gr.Textbox(label="Reasoning")
198
+ where_clause_output = gr.Textbox(label="Where Clause")
199
+
200
+
201
+ make_query_complete_bt = gr.Button("Complete Query")
202
+ complete_query_output = gr.Textbox(label="Complete Query")
203
+ make_query_complete_bt.click(fn=complete_query, inputs=where_clause_output, outputs=[complete_query_output])
204
+ submit_btn.click(fn=talk_to_llm, inputs=user_prompt, outputs=[reasoning_output, where_clause_output])
205
+
206
+ create_tap_url_bt = gr.Button("Create TAP URL")
207
+ download_data_output = gr.Markdown()
208
+ create_tap_url_bt.click(fn=create_markdown_url_from_query, inputs=complete_query_output, outputs=[download_data_output])
209
+
210
+ #demo.launch(server_name="0.0.0.0", server_port=7861, share=True, debug=True)
211
+ demo.launch()
212
+
213
+
214
+ #process_queries()