
Introduced a new `local_contact_router` to handle creation of local contacts. The endpoint enforces role-based access control and ensures no duplication of email addresses. Updated the router exports for consistency and cleaned up a large test file to improve readability.
447 lines
20 KiB
Plaintext
447 lines
20 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"import json\n",
|
|
"\n",
|
|
"#from nbclient.client import timestamp\n",
|
|
"\n",
|
|
"import backend.aareDBclient as aareDBclient\n",
|
|
"from aareDBclient.rest import ApiException\n",
|
|
"from pprint import pprint\n",
|
|
"\n",
|
|
"#from app.data.data import sample\n",
|
|
"\n",
|
|
"#from aareDBclient import SamplesApi, ShipmentsApi, PucksApi\n",
|
|
"#from aareDBclient.models import SampleEventCreate, SetTellPosition\n",
|
|
"#from examples.examples import api_response\n",
|
|
"\n",
|
|
"print(aareDBclient.__version__)\n",
|
|
"\n",
|
|
"configuration = aareDBclient.Configuration(\n",
|
|
" #host = \"https://mx-aare-test.psi.ch:1492\"\n",
|
|
" host = \"https://127.0.0.1:8000\"\n",
|
|
")\n",
|
|
"\n",
|
|
"print(configuration.host)\n",
|
|
"\n",
|
|
"configuration.verify_ssl = False # Disable SSL verification\n",
|
|
"#print(dir(SamplesApi))"
|
|
],
|
|
"id": "3b7c27697a4d5c83"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"## Fetch all Shipments, list corresponding dewars and pucks\n",
|
|
"\n",
|
|
"from datetime import date, datetime\n",
|
|
"from aareDBclient import ShipmentsApi\n",
|
|
"from aareDBclient.models import Shipment\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" api_instance = aareDBclient.ShipmentsApi(api_client)\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Fetch all shipments\n",
|
|
" all_shipments_response = api_instance.fetch_shipments_shipments_get()\n",
|
|
"\n",
|
|
" # Print shipment names and their associated puck names\n",
|
|
" for shipment in all_shipments_response:\n",
|
|
" print(f\"Shipment ID: {shipment.id}, Shipment Name: {shipment.shipment_name}\")\n",
|
|
" if hasattr(shipment, 'dewars') and shipment.dewars: # Ensure 'dewars' exists\n",
|
|
" for dewar in shipment.dewars:\n",
|
|
" print(f\" Dewar ID: {dewar.id}, Dewar Name: {dewar.dewar_name}, Dewar Unique ID: {dewar.unique_id} \")\n",
|
|
"\n",
|
|
" if hasattr(dewar, 'pucks') and dewar.pucks: # Ensure 'pucks' exists\n",
|
|
" for puck in dewar.pucks:\n",
|
|
" print(f\" Puck ID: {puck.id}, Puck Name: {puck.puck_name}\")\n",
|
|
" else:\n",
|
|
" print(\" No pucks found in this dewar.\")\n",
|
|
" else:\n",
|
|
" print(\" No dewars found in this shipment.\")\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(f\"Exception when calling ShipmentsApi->fetch_shipments_shipments_get: {e}\")\n"
|
|
],
|
|
"id": "4955b858f2cef93e"
|
|
},
|
|
{
|
|
"metadata": {
|
|
"ExecuteTime": {
|
|
"end_time": "2025-02-25T15:47:34.956061Z",
|
|
"start_time": "2025-02-25T15:47:34.941372Z"
|
|
}
|
|
},
|
|
"cell_type": "code",
|
|
"source": [
|
|
"from datetime import date\n",
|
|
"from aareDBclient import LogisticsApi\n",
|
|
"from aareDBclient.models import LogisticsEventCreate # Import required model\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" api_instance = aareDBclient.LogisticsApi(api_client)\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Create payload using the required model\n",
|
|
" logistics_event_create = LogisticsEventCreate(\n",
|
|
" dewar_qr_code='923db239427869be',\n",
|
|
" location_qr_code='A2-X06SA',\n",
|
|
" transaction_type='incoming',\n",
|
|
" timestamp=date.today() # Adjust if the API expects datetime\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Pass the payload to the API function\n",
|
|
" api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n",
|
|
" logistics_event_create=logistics_event_create # Pass as an object\n",
|
|
" )\n",
|
|
" print(\"API Response:\", api_response)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Create payload using the required model\n",
|
|
" logistics_event_create = LogisticsEventCreate(\n",
|
|
" dewar_qr_code='923db239427869be',\n",
|
|
" location_qr_code='A2-X06SA',\n",
|
|
" transaction_type='refill',\n",
|
|
" timestamp=date.today() # Adjust if the API expects datetime\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Pass the payload to the API function\n",
|
|
" api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n",
|
|
" logistics_event_create=logistics_event_create # Pass as an object\n",
|
|
" )\n",
|
|
" print(\"API Response:\", api_response)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Create payload using the required model\n",
|
|
" logistics_event_create = LogisticsEventCreate(\n",
|
|
" dewar_qr_code='923db239427869be',\n",
|
|
" location_qr_code='X06DA-Beamline',\n",
|
|
" transaction_type='beamline',\n",
|
|
" timestamp=date.today() # Adjust if the API expects datetime\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Pass the payload to the API function\n",
|
|
" api_response = api_instance.scan_dewar_logistics_dewar_scan_post(\n",
|
|
" logistics_event_create=logistics_event_create # Pass as an object\n",
|
|
" )\n",
|
|
" print(\"API Response:\", api_response)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(f\"Exception when calling LogisticsApi->scan_dewar_logistics_dewar_scan_post: {e}\")\n"
|
|
],
|
|
"id": "8fd3638bffaecd23",
|
|
"outputs": [
|
|
{
|
|
"ename": "TypeError",
|
|
"evalue": "ApiClient.call_api() got an unexpected keyword argument 'path_params'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
|
|
"\u001B[0;31mTypeError\u001B[0m Traceback (most recent call last)",
|
|
"Cell \u001B[0;32mIn[43], line 19\u001B[0m\n\u001B[1;32m 15\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 16\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m \u001B[38;5;28mopen\u001B[39m(file_path, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mrb\u001B[39m\u001B[38;5;124m\"\u001B[39m) \u001B[38;5;28;01mas\u001B[39;00m file_data:\n\u001B[1;32m 17\u001B[0m \u001B[38;5;66;03m# Use the low-level call_api method; note that the files parameter here is\u001B[39;00m\n\u001B[1;32m 18\u001B[0m \u001B[38;5;66;03m# a dictionary with key matching the FastAPI parameter name.\u001B[39;00m\n\u001B[0;32m---> 19\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[43mapi_client\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcall_api\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 20\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;124;43mf\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43m/\u001B[39;49m\u001B[38;5;132;43;01m{\u001B[39;49;00m\u001B[43msample_id\u001B[49m\u001B[38;5;132;43;01m}\u001B[39;49;00m\u001B[38;5;124;43m/upload_images\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m 21\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mPOST\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m 22\u001B[0m \u001B[43m \u001B[49m\u001B[43mpath_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m{\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43msample_id\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[43msample_id\u001B[49m\u001B[43m}\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 23\u001B[0m \u001B[43m \u001B[49m\u001B[43mfiles\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m{\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43muploaded_file\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[43m(\u001B[49m\u001B[43mfilename\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mfile_data\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmime_type\u001B[49m\u001B[43m)\u001B[49m\u001B[43m}\u001B[49m\n\u001B[1;32m 24\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 25\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mAPI Response:\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 26\u001B[0m \u001B[38;5;28mprint\u001B[39m(response)\n",
|
|
"\u001B[0;31mTypeError\u001B[0m: ApiClient.call_api() got an unexpected keyword argument 'path_params'"
|
|
]
|
|
}
|
|
],
|
|
"execution_count": 43
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get a list of pucks that are \"at the beamline\"\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" # Create an instance of the API class\n",
|
|
" api_instance = aareDBclient.PucksApi(api_client)\n",
|
|
" get_pucks_at_beamline = aareDBclient.PucksApi(api_client)\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Create Return Address\n",
|
|
" api_response = api_instance.get_pucks_by_slot_pucks_slot_slot_identifier_get(slot_identifier='X06DA')\n",
|
|
" print(\"The response of PucksApi->get_pucks_by_slot_pucks_slot_slot_identifier_get:\\n\")\n",
|
|
" pprint(api_response)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(\"Exception when calling PucksApi->get_pucks_by_slot_pucks_slot_slot_identifier_get: %s\\n\" % e)"
|
|
],
|
|
"id": "9cf3457093751b61"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"from aareDBclient import SetTellPosition, SetTellPositionRequest\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" # Create an instance of the API class\n",
|
|
" api_instance = aareDBclient.PucksApi(api_client)\n",
|
|
"\n",
|
|
" # Payload with SetTellPosition objects\n",
|
|
" payload = SetTellPositionRequest(\n",
|
|
" tell=\"X06DA\",\n",
|
|
" #pucks=[\n",
|
|
" # SetTellPosition(puck_name='PSIMX074', segment='B', puck_in_segment=1),\n",
|
|
" # SetTellPosition(puck_name='PSIMX080', segment='B', puck_in_segment=2),\n",
|
|
" # SetTellPosition(puck_name='PSIMX081', segment='C', puck_in_segment=3),\n",
|
|
" # SetTellPosition(puck_name='PSIMX084', segment='C', puck_in_segment=4),\n",
|
|
" # SetTellPosition(puck_name='PSIMX104', segment='E', puck_in_segment=5),\n",
|
|
" # SetTellPosition(puck_name='PSIMX107', segment='E', puck_in_segment=1),\n",
|
|
" # SetTellPosition(puck_name='PSIMX117', segment='F', puck_in_segment=2),\n",
|
|
" #]\n",
|
|
" #pucks=[\n",
|
|
" # SetTellPosition(puck_name='PSIMX074', segment='F', puck_in_segment=1),\n",
|
|
" # SetTellPosition(puck_name='PSIMX080', segment='F', puck_in_segment=2),\n",
|
|
" # SetTellPosition(puck_name='PSIMX107', segment='A', puck_in_segment=1),\n",
|
|
" # SetTellPosition(puck_name='PSIMX117', segment='A', puck_in_segment=2),\n",
|
|
" #]\n",
|
|
" pucks=[\n",
|
|
" SetTellPosition(puck_name='PK006', segment='F', puck_in_segment=1),\n",
|
|
" SetTellPosition(puck_name='PK003', segment='F', puck_in_segment=2),\n",
|
|
" SetTellPosition(puck_name='PK002', segment='A', puck_in_segment=1),\n",
|
|
" SetTellPosition(puck_name='PK001', segment='A', puck_in_segment=2),\n",
|
|
" ]\n",
|
|
" #pucks = []\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Call the PUT method to update the tell_position\n",
|
|
" try:\n",
|
|
" api_response = api_instance.set_tell_positions_pucks_set_tell_positions_put(\n",
|
|
" set_tell_position_request=payload\n",
|
|
" ) # Pass the entire payload as a single parameter\n",
|
|
"\n",
|
|
" print(\"The response of PucksApi->pucks_puck_id_tell_position_put:\\n\")\n",
|
|
" pprint(api_response)\n",
|
|
"\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"Exception when calling PucksApi: {e}\")\n"
|
|
],
|
|
"id": "37e3eac6760150ee"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get puck_id puck_name sample_id sample_name of pucks in the tell\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" # Create an instance of the API class\n",
|
|
" api_instance = aareDBclient.PucksApi(api_client)\n",
|
|
"\n",
|
|
" # GET request: Fetch all pucks in the tell\n",
|
|
" try:\n",
|
|
" # Call the API method to fetch pucks\n",
|
|
" all_pucks_response = api_instance.get_pucks_with_tell_position_pucks_with_tell_position_get(tell='X06DA')\n",
|
|
"\n",
|
|
" # Debug response structure by printing it in JSON format\n",
|
|
" formatted_response = json.dumps(\n",
|
|
" [p.to_dict() for p in all_pucks_response], # Assuming the API response can be converted to dicts\n",
|
|
" indent=4 # Use indentation for readability\n",
|
|
" )\n",
|
|
" #print(\"The response of PucksApi->get_all_pucks_in_tell (formatted):\\n\")\n",
|
|
" #print(formatted_response)\n",
|
|
"\n",
|
|
" # Iterate through each puck and print information\n",
|
|
" for p in all_pucks_response:\n",
|
|
" print(f\"Puck ID: {p.id}, Puck Name: {p.puck_name}\")\n",
|
|
"\n",
|
|
" ## Check if the puck has any samples\n",
|
|
" if hasattr(p, 'samples') and p.samples: # Ensure 'samples' attribute exists and is not empty\n",
|
|
" for sample in p.samples:\n",
|
|
" print(f\" Sample ID: {sample.id}, Sample Name: {sample.sample_name}, Position: {sample.position}, Mount count: {sample.mount_count}\")\n",
|
|
" else:\n",
|
|
" print(\" No samples found in this puck.\")\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(\"Exception when calling PucksApi->get_all_pucks_in_tell: %s\\n\" % e)"
|
|
],
|
|
"id": "51578d944878db6a"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"from aareDBclient import SampleEventCreate\n",
|
|
"\n",
|
|
"# Create an event for a sample\n",
|
|
"\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" # Instance of the API client\n",
|
|
" api_instance = aareDBclient.SamplesApi(api_client)\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Define the payload with only `event_type`\n",
|
|
" sample_event_create = SampleEventCreate(\n",
|
|
" sample_id=58,\n",
|
|
" event_type=\"Mounted\" # Valid event type\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Debug the payload before sending\n",
|
|
" print(\"Payload being sent to API:\")\n",
|
|
" print(sample_event_create.json()) # Ensure it matches `SampleEventCreate`\n",
|
|
"\n",
|
|
" # Call the API\n",
|
|
" api_response = api_instance.create_sample_event_samples_samples_sample_id_events_post(\n",
|
|
" sample_id=58, # Ensure this matches a valid sample ID in the database\n",
|
|
" sample_event_create=sample_event_create\n",
|
|
" )\n",
|
|
"\n",
|
|
" print(\"API response:\")\n",
|
|
" #pprint(api_response)\n",
|
|
"\n",
|
|
" for p in api_response:\n",
|
|
" print(p)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(\"Exception when calling post_sample_event:\")\n",
|
|
" print(f\"Status Code: {e.status}\")\n",
|
|
" if e.body:\n",
|
|
" print(f\"Error Details: {e.body}\")\n"
|
|
],
|
|
"id": "4a0665f92756b486"
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": [
|
|
"### not working\n",
|
|
"with aareDBclient.ApiClient(configuration) as api_client:\n",
|
|
" # Create an instance of the Samples API class\n",
|
|
" api_instance = aareDBclient.SamplesApi(api_client)\n",
|
|
"\n",
|
|
" try:\n",
|
|
" # Get the last sample event\n",
|
|
" last_event_response = api_instance.get_last_sample_event_samples_samples_sample_id_events_last_get(27)\n",
|
|
" print(\"The response of get_last_sample_event:\\n\")\n",
|
|
" pprint(last_event_response)\n",
|
|
"\n",
|
|
" except ApiException as e:\n",
|
|
" print(\"Exception when calling get_last_sample_event: %s\\n\" % e)\n"
|
|
],
|
|
"id": "f1d171700d6cf7fe"
|
|
},
|
|
{
|
|
"metadata": {
|
|
"ExecuteTime": {
|
|
"end_time": "2025-02-26T08:45:41.872357Z",
|
|
"start_time": "2025-02-26T08:45:41.847822Z"
|
|
}
|
|
},
|
|
"cell_type": "code",
|
|
"source": [
|
|
"import os\n",
|
|
"import mimetypes\n",
|
|
"import requests\n",
|
|
"\n",
|
|
"# File path to the image\n",
|
|
"file_path = \"backend/tests/sample_image/IMG_1942.jpg\"\n",
|
|
"filename = os.path.basename(file_path)\n",
|
|
"mime_type, _ = mimetypes.guess_type(file_path)\n",
|
|
"if mime_type is None:\n",
|
|
" mime_type = \"application/octet-stream\"\n",
|
|
"\n",
|
|
"# Sample ID (ensure this exists on your backend)\n",
|
|
"sample_id = 58\n",
|
|
"\n",
|
|
"# Build the URL for the upload endpoint.\n",
|
|
"url = f\"https://127.0.0.1:8000/samples/{sample_id}/upload-images\"\n",
|
|
"\n",
|
|
"# Open the file and construct the files dictionary\n",
|
|
"with open(file_path, \"rb\") as file_data:\n",
|
|
" files = {\n",
|
|
" # Use key \"uploaded_file\" as required by your API\n",
|
|
" \"uploaded_file\": (filename, file_data, mime_type)\n",
|
|
" }\n",
|
|
" headers = {\n",
|
|
" \"accept\": \"application/json\"\n",
|
|
" }\n",
|
|
"\n",
|
|
" # Set verify=False to bypass certificate verification (only use in development)\n",
|
|
" response = requests.post(url, headers=headers, files=files, verify=False)\n",
|
|
"\n",
|
|
"# Check the API response\n",
|
|
"print(\"API Response:\")\n",
|
|
"print(response.status_code)\n",
|
|
"try:\n",
|
|
" print(response.json())\n",
|
|
"except Exception:\n",
|
|
" print(response.text)\n"
|
|
],
|
|
"id": "11f62976d2e7d9b1",
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"API Response:\n",
|
|
"200\n",
|
|
"{'message': '1 image uploaded successfully.', 'file': 'images/p20001, p20002/2025-02-26/Dewar Two/PK001/14/IMG_1942.jpg'}\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings\n",
|
|
" warnings.warn(\n"
|
|
]
|
|
}
|
|
],
|
|
"execution_count": 70
|
|
},
|
|
{
|
|
"metadata": {},
|
|
"cell_type": "code",
|
|
"outputs": [],
|
|
"execution_count": null,
|
|
"source": "help(api_instance.upload_sample_images_samples_samples_sample_id_upload_images_post)",
|
|
"id": "cb1b99e6327fff84"
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 2
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython2",
|
|
"version": "2.7.6"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|