diff --git a/ipyigv/ipyigv.py b/ipyigv/ipyigv.py index 453091a..8cee104 100644 --- a/ipyigv/ipyigv.py +++ b/ipyigv/ipyigv.py @@ -12,7 +12,6 @@ from .options import * -from .utils import widget_serialization_no_none from ._version import EXTENSION_VERSION PUBLIC_GENOMES_FILE = os.path.join(os.path.dirname(__file__), 'public_genomes.json') @@ -47,15 +46,15 @@ def __init__(self, **kwargs): # Widget properties are defined as traitlets. Any property tagged with `sync=True` # is automatically synced to the frontend *any* time it changes in Python. # It is synced back to Python from the frontend *any* time the model is touched. - genome = InstanceDict(ReferenceGenome).tag(sync=True, **widget_serialization_no_none) - tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) + genome = InstanceDict(ReferenceGenome).tag(sync=True, **widget_serialization) + tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) doubleClickDelay = Int(default_value=500).tag(sync=True) flanking = Int(default_value=1000).tag(sync=True) - genomeList = Unicode(allow_none=True).tag(sync=True, **widget_serialization_no_none) # optional URL - locus = (Unicode() | List(Unicode())).tag(sync=True, **widget_serialization_no_none) + genomeList = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # optional URL + locus = (Unicode() | List(Unicode())).tag(sync=True, **widget_serialization) minimumBases = Int(default_value=40).tag(sync=True) queryParametersSupported = Bool(default=False).tag(sync=True) - search = InstanceDict(SearchService, allow_none=True).tag(sync=True, **widget_serialization_no_none) + search = InstanceDict(SearchService, allow_none=True).tag(sync=True, **widget_serialization) showAllChromosomes = Bool(default_value=True).tag(sync=True) showAllChromosomeWidget = Bool(default_value=True).tag(sync=True) showNavigation = Bool(default_value=True).tag(sync=True) @@ -63,7 +62,7 @@ def __init__(self, **kwargs): showRuler = Bool(default_value=True).tag(sync=True) showCenterGuide = Bool(default_value=False).tag(sync=True) # trackDefaults = # missing documentation - roi = List(InstanceDict(AnnotationTrack)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(AnnotationTrack)).tag(sync=True, **widget_serialization) # regions of interest oauthToken = Unicode(allow_none = True).tag(sync=True) apiKey = Unicode(allow_none = True).tag(sync=True) clientId = Unicode(allow_none = True).tag(sync=True) diff --git a/ipyigv/options.py b/ipyigv/options.py index 4607e11..7ee5604 100644 --- a/ipyigv/options.py +++ b/ipyigv/options.py @@ -10,7 +10,6 @@ from ipywidgets.widgets.trait_types import Color, InstanceDict from ipywidgets.widgets import widget -from .utils import widget_serialization_no_none from ._version import EXTENSION_VERSION @@ -143,11 +142,11 @@ class AnnotationTrack(Track): nameField = Unicode(default_value = 'Name').tag(sync=True) maxRows = Int (default_value = 500).tag(sync=True) searchable = Bool(default_value=False).tag(sync=True) - filterTypes = List(Unicode, default_value=['chromosone', 'gene']).tag(sync=True, **widget_serialization_no_none) + filterTypes = List(Unicode, default_value=['chromosone', 'gene']).tag(sync=True, **widget_serialization) color = Color("rgb(0,0,150)").tag(sync=True) altColor = Color("rgb(0,0,150)").tag(sync=True) - colorBy = Instance(FieldColors, allow_none=True).tag(sync=True, **widget_serialization_no_none) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + colorBy = Instance(FieldColors, allow_none=True).tag(sync=True, **widget_serialization) + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -175,16 +174,16 @@ class AlignmentTrack(Track): samplingDepth = Int(100).tag(sync=True) alignmentRowHeight = Int(14).tag(sync=True) readgroup = Unicode("RG").tag(sync=True) - sortOption = Instance(SortOption, allow_none=True).tag(sync=True, **widget_serialization_no_none) + sortOption = Instance(SortOption, allow_none=True).tag(sync=True, **widget_serialization) showSoftClips = Bool(False).tag(sync=True) showMismatches = Bool(True).tag(sync=True) # Paired-end and mate-pair coloring options. - pairOrientation = Unicode(allow_none=True).tag(sync=True, **widget_serialization_no_none) # ff, fr, or rf - minFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization_no_none) - maxFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization_no_none) + pairOrientation = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # ff, fr, or rf + minFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization) + maxFragmentLength = Int(allow_none=True).tag(sync=True, **widget_serialization) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -203,7 +202,7 @@ class VariantTrack(Track): squishedCallHeight = Int(1).tag(sync=True) expandedCallHeight = Int(10).tag(sync=True) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest class Guideline(HasTraits): @@ -221,14 +220,14 @@ class WigTrack(Track): type = Unicode('wig', read_only=True).tag(sync=True) autoscale = Bool(True).tag(sync=True) - autoscaleGroup = Unicode(allow_none=True).tag(sync=True, **widget_serialization_no_none) + autoscaleGroup = Unicode(allow_none=True).tag(sync=True, **widget_serialization) min = Int(0).tag(sync=True) - max = Int(allow_none=True).tag(sync=True, **widget_serialization_no_none) + max = Int(allow_none=True).tag(sync=True, **widget_serialization) color = Color(default_value="rgb(150, 150, 150)").tag(sync=True) - altColor = Color(allow_none=True).tag(sync=True, **widget_serialization_no_none) - guideLines = List(trait=Instance(Guideline), allow_none=True).tag(sync=True, **widget_serialization_no_none) + altColor = Color(allow_none=True).tag(sync=True, **widget_serialization) + guideLines = List(trait=Instance(Guideline), allow_none=True).tag(sync=True, **widget_serialization) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -239,11 +238,11 @@ class SegTrack(Track): """ type = Unicode('seg', read_only=True).tag(sync=True) - isLog = Bool(allow_none=True).tag(sync=True, **widget_serialization_no_none) + isLog = Bool(allow_none=True).tag(sync=True, **widget_serialization) displayMode = Unicode("EXPANDED").tag(sync=True) # "EXPANDED", "SQUISHED", or "FILL" sort = InstanceDict(SortOrder).tag(sync=True, **widget_serialization) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -263,19 +262,19 @@ class SpliceJunctionsTrack(Track): labelMultiMappedReadCount = Bool(True).tag(sync=True) labelTotalReadCount = Bool(False).tag(sync=True) labelMotif = Bool(False).tag(sync=True) - labelAnnotatedJunction = Unicode(allow_none=True).tag(sync=True, **widget_serialization_no_none) + labelAnnotatedJunction = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # Filtering Options minUniquelyMappedReads = Int(0).tag(sync=True) minTotalReads = Int(0).tag(sync=True) maxFractionMultiMappedReads = Int(1).tag(sync=True) minSplicedAlignmentOverhang = Int(0).tag(sync=True) - hideStrand = Unicode(allow_none=True).tag(sync=True, **widget_serialization_no_none) # None, "+" or "-" + hideStrand = Unicode(allow_none=True).tag(sync=True, **widget_serialization) # None, "+" or "-" hideAnnotatedJunctions = Bool(False).tag(sync=True) hideUnannotatedJunctions = Bool(False).tag(sync=True) hideMotifs = List(Unicode).tag(sync=True, **widget_serialization) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -291,9 +290,9 @@ class GwasTrack (Track): # format = Unicode().tag(sync=True) # 'bed' or 'gwas' - format is already in Track -> validation only posteriorProbability = Bool(False).tag(sync=True) dotSize = Int(3).tag(sync=True) - columns = Dict(key_trait=Unicode, value_trait=Int, allow_none=True).tag(sync=True, **widget_serialization_no_none) + columns = Dict(key_trait=Unicode, value_trait=Int, allow_none=True).tag(sync=True, **widget_serialization) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest @register @@ -307,7 +306,7 @@ class InteractionTrack (Track): arcOrientation = Bool(True).tag(sync=True) thickness = Int(2).tag(sync=True) - roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) # regions of interest + roi = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) # regions of interest class Exon(HasTraits): @@ -357,8 +356,8 @@ class ReferenceGenome(Widget): indexURL = Unicode(allow_none=True).tag(sync=True) cytobandURL = Unicode(allow_none=True).tag(sync=True) aliasURL = Unicode(allow_none=True).tag(sync=True) - indexed = Bool(default_value=False).tag(sync=True) - tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization_no_none) + indexed = Bool(allow_none=True, default_value=None).tag(sync=True) + tracks = List(InstanceDict(Track)).tag(sync=True, **widget_serialization) chromosomeOrder = Unicode(allow_none=True).tag(sync=True) headers = Dict().tag(sync=True) wholeGenomeView = Bool(default_value=True).tag(sync=True) diff --git a/ipyigv/utils.py b/ipyigv/utils.py index c58e950..af11ab1 100644 --- a/ipyigv/utils.py +++ b/ipyigv/utils.py @@ -1,11 +1,19 @@ from ipywidgets import Widget, widget_serialization +def is_json_valid(v): + if v is None: + return False + elif isinstance(v, str): + return (v != "") + else: + return True + def _widget_to_json_no_none(x, obj): if isinstance(x, dict): - return {k: _widget_to_json_no_none(v, obj) for k, v in x.items() if v is not None} + return {k: _widget_to_json_no_none(v, obj) for k, v in x.items() if v not in (None, "")} elif isinstance(x, (list, tuple)): - return [_widget_to_json_no_none(v, obj) for v in x if v is not None] + return [_widget_to_json_no_none(v, obj) for v in x if v not in (None, "")] elif isinstance(x, Widget): return "IPY_MODEL_" + x.model_id else: diff --git a/js/package.json b/js/package.json index 12391df..d9054c0 100644 --- a/js/package.json +++ b/js/package.json @@ -36,8 +36,9 @@ "@jupyterlab/builder": "^3.0.0", "css-loader": "^5.0.1", "rimraf": "^2.6.1", + "schema-utils": "2.6.6", "style-loader": "^2.0.0", - "webpack": "^4.44.2", + "webpack": "^4.46.0", "webpack-cli": "^3.1.2" }, "jupyterlab": { diff --git a/js/src/ipyigv.js b/js/src/ipyigv.js index a582ded..8cd9a7d 100644 --- a/js/src/ipyigv.js +++ b/js/src/ipyigv.js @@ -7,10 +7,6 @@ import '../css/widget.css' import { MODULE_NAME, MODULE_VERSION } from './version' -// When serialiazing the entire widget state for embedding, only values that -// differ from the defaults will be specified. - - export class TrackModel extends widgets.WidgetModel { defaults () { return _.extend(super.defaults(), { @@ -22,6 +18,21 @@ export class TrackModel extends widgets.WidgetModel { _view_module_version : MODULE_VERSION, }); }; + + // returns a dictionary representing a track which igv.js can take in its configuration + to_dict(include_empty = false) { + let keys = Object.keys(this.attributes).filter(k => !k.startsWith("_")) + // removing empty values unless specified otherwise + .filter(k=> (include_empty || !([null, undefined, ""].includes(this.get(k))))); + + var dict = keys.reduce((result, key)=> ({...result, [key]:this.get(key)}), {}); + + if (keys.includes('roi')) { + dict['roi'] = dict['roi'].map(track => track.to_dict(include_empty)); + }; + console.log ("Finished generating dictionary from TrackModel", dict); + return dict ; + }; }; @@ -36,6 +47,23 @@ export class ReferenceGenomeModel extends widgets.WidgetModel { _view_module_version : MODULE_VERSION, }); }; + + // returns a dictionary representing a genome which igv.js can take in its configuration + to_dict(include_empty = false) { + let keys = Object.keys(this.attributes).filter(k => !k.startsWith("_")) + // removing empty values unless specified otherwise + .filter(k=> (include_empty || !([null, undefined, ""].includes(this.get(k))))); + + var dict = keys.reduce((result, key)=> ({...result, [key]:this.get(key)}), {}); + + // special treatment for tracks + if (keys.includes('tracks')) { + let tracks = dict['tracks']; + dict['tracks'] = tracks.map(track=> track.to_dict(include_empty)); + }; + console.log ("Finished generating dictionary from ReferenceGenomeView", dict); + return dict ; + }; }; ReferenceGenomeModel.serializers = _.extend({ @@ -71,6 +99,39 @@ export class IgvModel extends widgets.DOMWidgetModel { this.trigger('search', symbol); } }; + + // returns a dictionary representing a genome which igv.js can take in its configuration + to_dict(include_empty = false) { + var keys = Object.keys(this.attributes).filter(k => !k.startsWith("_")) + // removing the layout attribute -- not related to igv + .filter(k=> (k!='layout')) + // removing empty values unless specified otherwise + .filter(k=> (include_empty || !([null, undefined, ""].includes(this.get(k))))); + + var dict = keys.reduce((result, key)=> ({...result, [key]:this.get(key)}), {}); + + // special treatment for tracks + if (keys.includes('tracks')) { + let tracks = dict['tracks']; + dict['tracks'] = tracks.map(track=> track.to_dict(include_empty)); + }; + + // special treatment for regions of interest + if (keys.includes('roi')) { + let roi = dict['roi']; + dict['roi'] = roi.map(roi=> roi.to_dict(include_empty)); + }; + + + // special treatment for genome + if (keys.includes('genome')) { // should always be the case + let genome = dict['genome']; + dict['genome'] = genome.to_dict(include_empty); + }; + + console.log ("Finished generating dictionary from IgvModel", dict); + return dict ; + }; }; IgvModel.serializers = _.extend({ @@ -117,58 +178,8 @@ export class IgvBrowser extends widgets.DOMWidgetView { super.render(); this.igvDiv = document.createElement("div"); - var referenceGenome = this.model.get('genome'); - var tracks = this.model.get('tracks'); - var roi = this.model.get('roi'); - var doubleClickDelay = this.model.get('doubleClickDelay'); - var flanking = this.model.get('flanking'); - var genomeList = this.model.get('genomeList'); - var locus = this.model.get('locus'); - var minimumBases = this.model.get('minimumBases'); - var queryParametersSupported = this.model.get('queryParametersSupported'); - var search = this.model.get('search'); - var showAllChromosomes = this.model.get('showAllChromosomes'); - var showAllChromosomeWidget = this.model.get('showAllChromosomeWidget'); - var showNavigation = this.model.get('showNavigation'); - var showSVGButton = this.model.get('showSVGButton'); - var showRuler = this.model.get('showRuler'); - var showCenterGuide = this.model.get('showCenterGuide'); - var oauthToken = this.model.get('oauthToken'); - var apiKey = this.model.get('apiKey'); - var clientId = this.model.get('clientId'); - - - var options = { - reference: referenceGenome, - tracks: tracks, - roi: roi, - doubleClickDelay: doubleClickDelay, - flanking: flanking, - genomeList: genomeList, - locus: locus, - minimumBases: minimumBases, - queryParametersSupported: queryParametersSupported, - showAllChromosomes:showAllChromosomes, - showAllChromosomeWidget: showAllChromosomeWidget, - showNavigation: showNavigation, - showSVGButton: showSVGButton, - showRuler: showRuler, - showCenterGuide: showCenterGuide, - }; - - if (search) { - options['search']=search - } - if (oauthToken) { - options['oauthToken']=oauthToken - } - if (apiKey) { - options['apiKey']=apiKey - } - if (clientId) { - options['clientId']=clientId - } + var options = this.model.to_dict() console.log("rendering browser", options); this.browser = igv.createBrowser(this.igvDiv, options) .then((browser) => { @@ -314,12 +325,3 @@ export class IgvBrowser extends widgets.DOMWidgetView { } - -// module.exports = { -// IgvModel: IgvModel, -// IgvBrowser: IgvBrowser, -// ReferenceGenomeView: ReferenceGenomeView, -// ReferenceGenomeModel: ReferenceGenomeModel, -// TrackView: TrackView, -// TrackModel: TrackModel, -// }; diff --git a/notebooks/ipyigv.ipynb b/notebooks/ipyigv.ipynb index 35612e5..0c53291 100644 --- a/notebooks/ipyigv.ipynb +++ b/notebooks/ipyigv.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -21,25 +21,44 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "genomeDict=igv.PUBLIC_GENOMES.hg38" + "genomeDict={ 'id': \"hg38\", 'name': 'Human (GRCh38/hg38)',\n", + " 'fastaURL': 'https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa',\n", + " 'indexURL': 'https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai',\n", + " 'cytobandURL': 'https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz',\n", + " 'tracks': [{'name': 'Refseq Genes',\n", + " 'format': 'refgene',\n", + " 'url': 'https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/refGene.txt.gz',\n", + " 'indexed': False,\n", + " 'visibilityWindow': -1,\n", + " 'removable': False,\n", + " 'order': 1000000}]}" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ReferenceGenome(cytobandURL='https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz', fastaURL='https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa', id='hg38', indexURL='https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai', name='Human (GRCh38/hg38)', tracks=[AnnotationTrack(colorBy=None, filterTypes=['chromosone', 'gene'], format='refgene', name='Refseq Genes', order=1000000, removable=False, url='https://s3.dualstack.us-east-1.amazonaws.com/igv.org.genomes/hg38/refGene.txt.gz')])\n" + ] + } + ], "source": [ - "genome = ReferenceGenome(**genomeDict)" + "genome = ReferenceGenome(**genomeDict)\n", + "print(genome)" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -48,13 +67,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "72046f0dd69f4344a5704ee1d5464f1a", + "model_id": "ef795fc22d9c45ea8c9f7d8df254fc98", "version_major": 2, "version_minor": 0 }, @@ -79,7 +98,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -94,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -103,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -112,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -128,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -142,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -151,7 +170,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -167,14 +186,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "search\n" + "Search completed. Check the widget instance for results.\n" ] } ], @@ -192,14 +211,14 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Dumping JSON to browser.out\n" + "Dumping browser configuration to browser.out\n" ] } ], @@ -209,7 +228,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 15, "metadata": { "scrolled": true }, @@ -217,12 +236,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9a164e5ec14b4b95b1b8257b3f6499ad", + "model_id": "c966345122244b7ab1d5a116c4633599", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "Output(outputs=({'output_type': 'stream', 'text': \"{'version': '2.7.0', 'reference': {'id': 'hg38', 'name': 'H…" + "Output(outputs=({'name': 'stdout', 'text': \"{'version': '2.7.0', 'reference': {'cytobandURL': 'https://s3.dual…" ] }, "metadata": {}, @@ -238,38 +257,38 @@ "metadata": {}, "source": [ "## Charging local files\n", - "NB: `igv.js` tries to load a file `undefined.fai` which causes an error. Maybe due to the use of `localhost:8000` -- activate it with `python -m http.server` in your files directory." + "Just load your own local files through Jupyter via \"http://localhost:8888/files/pathToDir/filename\". NB: modify the paths below accordingly." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "genome2 = {\n", " 'name': 'Example chr6p',\n", - " 'fastaURL': 'http://localhost:8000/chr6p.fa',\n", - " 'indexURL': 'http://localhost:8000/chr6p.fa.fai',\n", + " 'fastaURL': 'http://localhost:8888/files/DatasetsIGV2/chr6p.fa',\n", + " 'indexURL': 'http://localhost:8888/files/DatasetsIGV2/chr6p.fa.fai',\n", "}" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "pgf6p_on_chr6p_track = {'name': 'PGF 6p on chr6p',\n", " 'format': 'refgene',\n", - " 'url': 'http://localhost:8000/PGF_6p_on_chr6p.bam',\n", - " 'indexURL': 'http://localhost:8000/PGF_6p_on_chr6p.bai',\n", + " 'url': 'http://localhost:8888/files/PGF_6p_on_chr6p.bam',\n", + " 'indexURL': 'http://localhost:8888/files/PGF_6p_on_chr6p.bai',\n", " }" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -278,18 +297,18 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "08c6dcc3894843c290738b319e53c84b", + "model_id": "db7743b640d44a73a96a52111eb0c33c", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "IgvBrowser(genome=ReferenceGenome(fastaURL='http://localhost:8000/chr6p.fa', indexURL='http://localhost:8000/c…" + "IgvBrowser(genome=ReferenceGenome(fastaURL='http://localhost:8888/files/DatasetsIGV2/chr6p.fa', indexURL='http…" ] }, "metadata": {}, @@ -302,72 +321,10 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "import urllib.request" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "ename": "URLError", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mConnectionRefusedError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36mdo_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1341\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1342\u001b[0;31m h.request(req.get_method(), req.selector, req.data, headers,\n\u001b[0m\u001b[1;32m 1343\u001b[0m encode_chunked=req.has_header('Transfer-encoding'))\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1254\u001b[0m \u001b[0;34m\"\"\"Send a complete request to the server.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1255\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_send_request\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36m_send_request\u001b[0;34m(self, method, url, body, headers, encode_chunked)\u001b[0m\n\u001b[1;32m 1300\u001b[0m \u001b[0mbody\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_encode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'body'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1301\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mendheaders\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1302\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36mendheaders\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1249\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mCannotSendHeader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1250\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_send_output\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmessage_body\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mencode_chunked\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mencode_chunked\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1251\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36m_send_output\u001b[0;34m(self, message_body, encode_chunked)\u001b[0m\n\u001b[1;32m 1009\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_buffer\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1010\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1011\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 949\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauto_open\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 950\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 951\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/http/client.py\u001b[0m in \u001b[0;36mconnect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 920\u001b[0m \u001b[0;34m\"\"\"Connect to the host and port specified in __init__.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 921\u001b[0;31m self.sock = self._create_connection(\n\u001b[0m\u001b[1;32m 922\u001b[0m (self.host,self.port), self.timeout, self.source_address)\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/socket.py\u001b[0m in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address)\u001b[0m\n\u001b[1;32m 842\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 843\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 844\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/socket.py\u001b[0m in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address)\u001b[0m\n\u001b[1;32m 830\u001b[0m \u001b[0msock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbind\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource_address\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 831\u001b[0;31m \u001b[0msock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msa\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 832\u001b[0m \u001b[0;31m# Break explicitly a reference cycle\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mConnectionRefusedError\u001b[0m: [Errno 61] Connection refused", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mURLError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0murl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0murllib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'http://localhost:8000/chr6p.fa.fai'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36murlopen\u001b[0;34m(url, data, timeout, cafile, capath, cadefault, context)\u001b[0m\n\u001b[1;32m 212\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0mopener\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_opener\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 214\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mopener\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 215\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 216\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0minstall_opener\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mopener\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36mopen\u001b[0;34m(self, fullurl, data, timeout)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 516\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maudit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'urllib.Request'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 517\u001b[0;31m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mreq\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 518\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 519\u001b[0m \u001b[0;31m# post-process response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36m_open\u001b[0;34m(self, req, data)\u001b[0m\n\u001b[1;32m 532\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 533\u001b[0m \u001b[0mprotocol\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 534\u001b[0;31m result = self._call_chain(self.handle_open, protocol, protocol +\n\u001b[0m\u001b[1;32m 535\u001b[0m '_open', req)\n\u001b[1;32m 536\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36m_call_chain\u001b[0;34m(self, chain, kind, meth_name, *args)\u001b[0m\n\u001b[1;32m 492\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhandler\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mhandlers\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 493\u001b[0m \u001b[0mfunc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandler\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmeth_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 494\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 495\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 496\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36mhttp_open\u001b[0;34m(self, req)\u001b[0m\n\u001b[1;32m 1369\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1370\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mhttp_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1371\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdo_open\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mHTTPConnection\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1372\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1373\u001b[0m \u001b[0mhttp_request\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAbstractHTTPHandler\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdo_request_\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/miniconda3/envs/widgets/lib/python3.9/urllib/request.py\u001b[0m in \u001b[0;36mdo_open\u001b[0;34m(self, http_class, req, **http_conn_args)\u001b[0m\n\u001b[1;32m 1343\u001b[0m encode_chunked=req.has_header('Transfer-encoding'))\n\u001b[1;32m 1344\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mOSError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# timeout error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1345\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mURLError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1346\u001b[0m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetresponse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1347\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mURLError\u001b[0m: " - ] - } - ], - "source": [ - "url = urllib.request.urlopen('http://localhost:8000/chr6p.fa.fai')" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'url' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'utf-8'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'url' is not defined" - ] - } - ], - "source": [ - "print(url.read(100).decode('utf-8'))" - ] + "source": [] }, { "cell_type": "code", @@ -393,7 +350,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.0" + "version": "3.9.1" } }, "nbformat": 4,