Loading Conf/PostgreSQL.json 0 → 100644 +7 −0 Original line number Diff line number Diff line { "user": "postgres", "host": "131.154.98.131", "database": "spoke3", "password": "postgres", "port": 5432 } Conf/REST.json 0 → 100644 +3 −0 Original line number Diff line number Diff line { "port": 3000 } Conf/Redis.json 0 → 100644 +4 −0 Original line number Diff line number Diff line { "host": "127.0.0.1", "port": 6379 } IVOA.js 0 → 100644 +101 −0 Original line number Diff line number Diff line // IVOA // IVOA implementation import { InternalError, IO, performIO } from "./Lib/IO.js"; import { putStr, readFile } from "./Lib/IO.js"; import { connPostgreSQL, fetchRows, quitPostgreSQL } from "./Lib/PostgreSQL.js"; import { startRESTServer, readRESTPort } from "./Lib/REST.js"; import { buildVOTablesFromRows } from "./Lib/VOTable.js"; /** * Serves the static /tap HTML landing page (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - HTML content */ async function IVOA_tapEndpoint(req, IO) { return await readFile("Stat/tap.html")(IO); } /** * Serves the static /availability XML response (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content */ async function IVOA_availabilityEndpoint(req, IO) { return await readFile("Stat/availability.xml")(IO); } /** * Serves the static /capabilities XML response (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content */ async function IVOA_capabilitiesEndpoint(req, IO) { return await readFile("Stat/capabilities.xml")(IO); } /** * IVOA_tablesEndpoint : Request -> IO -> IO String * Executes an SQL query from file and returns a VOTable representation (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content in VOTable format or error message */ async function IVOA_tablesEndpoint(req, IO) { const query = await readFile("Query/tables.sql")(IO); const conn = await connPostgreSQL()(IO); const result = await fetchRows(conn, query, [])(IO); await quitPostgreSQL(conn)(IO); if (result.tag === "nothing") { return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>'; } return buildVOTablesFromRows(result.value); } /** * Main entry point for the IVOA TAP and DataLink server (functional signature: IO -> IO ()). * * @param {Symbol} IO - IO token * @returns {Promise<void>} - Starts the server and binds all routes */ async function IVOA_main(IO) { await putStr("IVOA server started")(IO); const port = await readRESTPort(IO); startRESTServer(port, [ { path: "/tap", endpoint: IVOA_tapEndpoint }, { path: "/tap/availability", endpoint: IVOA_availabilityEndpoint }, { path: "/tap/capabilities", endpoint: IVOA_capabilitiesEndpoint }, { path: "/tap/tables", endpoint: IVOA_tablesEndpoint }, ])(IO); } /** * Wraps the program execution in a safe IO environment (functional signature: () -> IO ()). * * @returns {IO} - The IO token after the execution */ function mainExpression() { return performIO((IO) => IVOA_main(IO)); } try { await mainExpression(); } catch (e) { if (e instanceof InternalError) { await putStr("ERROR: " + e.message)(IO); } else { throw e; } } IVOA.py 0 → 100644 +103 −0 Original line number Diff line number Diff line # IVOA # IVOA implementation from Lib.IO import InternalError, IO, performIO from Lib.IO import putStr, readFile from Lib.PostgreSQL import connPostgreSQL, fetchRows, quitPostgreSQL from Lib.REST import startRESTServer, readRESTPort from Lib.VOTable import buildVOTablesFromRows async def IVOA_tapEndpoint(req, IO): """ Serves the static /tap HTML landing page (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - HTML content """ return await readFile("Stat/tap.html")(IO) async def IVOA_availabilityEndpoint(req, IO): """ Serves the static /availability XML response (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content """ return await readFile("Stat/availability.xml")(IO) async def IVOA_capabilitiesEndpoint(req, IO): """ Serves the static /capabilities XML response (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content """ return await readFile("Stat/capabilities.xml")(IO) async def IVOA_tablesEndpoint(req, IO): """ Executes an SQL query from file and returns a VOTable representation (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content in VOTable format or error message """ query = await readFile("Query/tables.sql")(IO) conn = await connPostgreSQL()(IO) result = await fetchRows(conn, query, [])(IO) await quitPostgreSQL(conn)(IO) if result["tag"] == "nothing": return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>' return buildVOTablesFromRows(result["value"]) async def IVOA_main(IO): """ Main entry point for the IVOA TAP and DataLink server (functional signature: IO -> IO ()). @param IO: IO token @returns: Coroutine[None] - Starts the server and binds all routes """ await putStr("IVOA server started")(IO) port = readRESTPort(IO) await startRESTServer( port, [ {"path": "/tap", "endpoint": IVOA_tapEndpoint}, {"path": "/tap/availability", "endpoint": IVOA_availabilityEndpoint}, {"path": "/tap/capabilities", "endpoint": IVOA_capabilitiesEndpoint}, {"path": "/tap/tables", "endpoint": IVOA_tablesEndpoint}, ], )(IO) await asyncio.Event().wait() def mainExpression(): """ Wraps the program execution in a safe IO environment (functional signature: () -> IO ()). @returns: IO () - The IO token after the execution """ return performIO(lambda IO: IVOA_main(IO)) if __name__ == "__main__": import asyncio try: asyncio.run(mainExpression()) except InternalError as e: asyncio.run(putStr("ERROR: " + str(e))(IO)) except Exception as e: raise Loading
Conf/PostgreSQL.json 0 → 100644 +7 −0 Original line number Diff line number Diff line { "user": "postgres", "host": "131.154.98.131", "database": "spoke3", "password": "postgres", "port": 5432 }
Conf/Redis.json 0 → 100644 +4 −0 Original line number Diff line number Diff line { "host": "127.0.0.1", "port": 6379 }
IVOA.js 0 → 100644 +101 −0 Original line number Diff line number Diff line // IVOA // IVOA implementation import { InternalError, IO, performIO } from "./Lib/IO.js"; import { putStr, readFile } from "./Lib/IO.js"; import { connPostgreSQL, fetchRows, quitPostgreSQL } from "./Lib/PostgreSQL.js"; import { startRESTServer, readRESTPort } from "./Lib/REST.js"; import { buildVOTablesFromRows } from "./Lib/VOTable.js"; /** * Serves the static /tap HTML landing page (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - HTML content */ async function IVOA_tapEndpoint(req, IO) { return await readFile("Stat/tap.html")(IO); } /** * Serves the static /availability XML response (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content */ async function IVOA_availabilityEndpoint(req, IO) { return await readFile("Stat/availability.xml")(IO); } /** * Serves the static /capabilities XML response (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content */ async function IVOA_capabilitiesEndpoint(req, IO) { return await readFile("Stat/capabilities.xml")(IO); } /** * IVOA_tablesEndpoint : Request -> IO -> IO String * Executes an SQL query from file and returns a VOTable representation (functional signature: Request -> IO -> IO String). * * @param {Request} req - Incoming HTTP request * @param {Symbol} IO - IO token * @returns {Promise<string>} - XML content in VOTable format or error message */ async function IVOA_tablesEndpoint(req, IO) { const query = await readFile("Query/tables.sql")(IO); const conn = await connPostgreSQL()(IO); const result = await fetchRows(conn, query, [])(IO); await quitPostgreSQL(conn)(IO); if (result.tag === "nothing") { return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>'; } return buildVOTablesFromRows(result.value); } /** * Main entry point for the IVOA TAP and DataLink server (functional signature: IO -> IO ()). * * @param {Symbol} IO - IO token * @returns {Promise<void>} - Starts the server and binds all routes */ async function IVOA_main(IO) { await putStr("IVOA server started")(IO); const port = await readRESTPort(IO); startRESTServer(port, [ { path: "/tap", endpoint: IVOA_tapEndpoint }, { path: "/tap/availability", endpoint: IVOA_availabilityEndpoint }, { path: "/tap/capabilities", endpoint: IVOA_capabilitiesEndpoint }, { path: "/tap/tables", endpoint: IVOA_tablesEndpoint }, ])(IO); } /** * Wraps the program execution in a safe IO environment (functional signature: () -> IO ()). * * @returns {IO} - The IO token after the execution */ function mainExpression() { return performIO((IO) => IVOA_main(IO)); } try { await mainExpression(); } catch (e) { if (e instanceof InternalError) { await putStr("ERROR: " + e.message)(IO); } else { throw e; } }
IVOA.py 0 → 100644 +103 −0 Original line number Diff line number Diff line # IVOA # IVOA implementation from Lib.IO import InternalError, IO, performIO from Lib.IO import putStr, readFile from Lib.PostgreSQL import connPostgreSQL, fetchRows, quitPostgreSQL from Lib.REST import startRESTServer, readRESTPort from Lib.VOTable import buildVOTablesFromRows async def IVOA_tapEndpoint(req, IO): """ Serves the static /tap HTML landing page (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - HTML content """ return await readFile("Stat/tap.html")(IO) async def IVOA_availabilityEndpoint(req, IO): """ Serves the static /availability XML response (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content """ return await readFile("Stat/availability.xml")(IO) async def IVOA_capabilitiesEndpoint(req, IO): """ Serves the static /capabilities XML response (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content """ return await readFile("Stat/capabilities.xml")(IO) async def IVOA_tablesEndpoint(req, IO): """ Executes an SQL query from file and returns a VOTable representation (functional signature: Request -> IO -> IO String). @param req: Incoming HTTP request @param IO: IO token @returns: Coroutine[str] - XML content in VOTable format or error message """ query = await readFile("Query/tables.sql")(IO) conn = await connPostgreSQL()(IO) result = await fetchRows(conn, query, [])(IO) await quitPostgreSQL(conn)(IO) if result["tag"] == "nothing": return '<?xml version="1.0" encoding="UTF-8"?><error>No tables found</error>' return buildVOTablesFromRows(result["value"]) async def IVOA_main(IO): """ Main entry point for the IVOA TAP and DataLink server (functional signature: IO -> IO ()). @param IO: IO token @returns: Coroutine[None] - Starts the server and binds all routes """ await putStr("IVOA server started")(IO) port = readRESTPort(IO) await startRESTServer( port, [ {"path": "/tap", "endpoint": IVOA_tapEndpoint}, {"path": "/tap/availability", "endpoint": IVOA_availabilityEndpoint}, {"path": "/tap/capabilities", "endpoint": IVOA_capabilitiesEndpoint}, {"path": "/tap/tables", "endpoint": IVOA_tablesEndpoint}, ], )(IO) await asyncio.Event().wait() def mainExpression(): """ Wraps the program execution in a safe IO environment (functional signature: () -> IO ()). @returns: IO () - The IO token after the execution """ return performIO(lambda IO: IVOA_main(IO)) if __name__ == "__main__": import asyncio try: asyncio.run(mainExpression()) except InternalError as e: asyncio.run(putStr("ERROR: " + str(e))(IO)) except Exception as e: raise