| 1 |  |  | import contextlib | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | import webbrowser | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | import strawberry | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | from starlette.applications import Starlette | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | from starlette.requests import Request | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | from starlette.responses import RedirectResponse | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | from starlette.schemas import SchemaGenerator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | from starlette.types import ASGIApp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | from strawberry.asgi import GraphQL | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | from graphinate.server.starlette import routes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | DEFAULT_PORT: int = 8072 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | GRAPHQL_ROUTE_PATH = "/graphql" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  | def _openapi_schema(request: Request) -> ASGIApp: | 
            
                                                                        
                            
            
                                    
            
            
                | 20 |  |  |     """ | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  |     Generates an OpenAPI schema for the GraphQL API and other routes. | 
            
                                                                        
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 23 |  |  |     Args: | 
            
                                                                        
                            
            
                                    
            
            
                | 24 |  |  |         request (Request): The HTTP request object. | 
            
                                                                        
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 26 |  |  |     Returns: | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |         ASGIApp: An OpenAPI response containing the schema for the specified routes. | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |     """ | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |     schema_data = { | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |         'openapi': '3.0.0', | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |         'info': {'title': 'Graphinate API', 'version': '0.9.0'}, | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |         'paths': { | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |             '/graphql': {'get': {'responses': {200: {'description': 'GraphQL'}}}}, | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |             '/graphiql': {'get': {'responses': {200: {'description': 'GraphiQL UI.'}}}}, | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |             '/metrics': {'get': {'responses': {200: {'description': 'Prometheus metrics.'}}}}, | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |             '/viewer': {'get': {'responses': {200: {'description': '3D Force-Directed Graph Viewer'}}}}, | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |             '/voyager': {'get': {'responses': {200: {'description': 'Voyager GraphQL Schema Viewer'}}}} | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |     } | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |     schema = SchemaGenerator(schema_data) | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |     return schema.OpenAPIResponse(request=request) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | def _graphql_app(graphql_schema: strawberry.Schema) -> strawberry.asgi.GraphQL: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     Creates a Strawberry GraphQL app with the provided schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         graphql_schema: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     Returns: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         strawberry.asgi.GraphQL: The GraphQL app configured with the provided schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     graphql_app = GraphQL(graphql_schema, graphiql=True) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     return graphql_app | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  | def _starlette_app(graphql_app: strawberry.asgi.GraphQL | None = None, port: int = DEFAULT_PORT, **kwargs) -> Starlette: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     def open_url(endpoint): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         webbrowser.open(f'http://localhost:{port}/{endpoint}') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     @contextlib.asynccontextmanager | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |     async def lifespan(app: Starlette):  # pragma: no cover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         if kwargs.get('browse'): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             open_url('viewer') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         yield | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     app = Starlette( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         lifespan=lifespan, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         routes=routes() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     from starlette_prometheus import PrometheusMiddleware, metrics | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     app.add_middleware(PrometheusMiddleware) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     app.add_route("/metrics", metrics) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     if graphql_app: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         app.add_route(GRAPHQL_ROUTE_PATH, graphql_app) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |         app.add_websocket_route(GRAPHQL_ROUTE_PATH, graphql_app) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |         app.add_route("/schema", route=_openapi_schema, include_in_schema=False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         app.add_route("/openapi.json", route=_openapi_schema, include_in_schema=False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     async def redirect_to_viewer(request): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         return RedirectResponse(url='/viewer') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     app.add_route('/', redirect_to_viewer) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     return app | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  | def server(graphql_schema: strawberry.Schema, port: int = DEFAULT_PORT, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |     Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         graphql_schema: The Strawberry GraphQL schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         port: The port number to run the server on. Defaults to 8072. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |     Returns: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |     graphql_app = _graphql_app(graphql_schema) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     app = _starlette_app(graphql_app, port=port, **kwargs) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     import uvicorn | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     uvicorn.run(app, host='0.0.0.0', port=port) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 108 |  |  | __all__ = ['server'] | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |  |