diff --git a/cartoframes/layer.py b/cartoframes/layer.py
index 6ddaa641..49143e33 100644
--- a/cartoframes/layer.py
+++ b/cartoframes/layer.py
@@ -60,9 +60,7 @@ class BaseMap(AbstractLayer):
 
         self.source = source
         self.labels = labels
-        stem = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
-        if source == 'voyager':
-            stem += 'rastertiles'
+        stem = 'https://{s}.basemaps.cartocdn.com/rastertiles/'
 
         if self.is_basic():
             if only_labels:

Update basemap URLs
Basemap URL domains have fastly.net (e.g. here: https://github.com/CartoDB/cartoframes/blob/master/cartoframes/layer.py#L63), this should be replaced by basemaps.cartocdn.com in whole code and tests:
* Old: https://cartodb-basemaps-{s}.global.ssl.fastly.net/
* New: https://{s}.basemaps.cartocdn.com/

Other URL parts remain same. Needed for https://github.com/CartoDB/lbs-services/issues/16
diff --git a/test/test_layer.py b/test/test_layer.py
index e24117b4..c10e2133 100644
--- a/test/test_layer.py
+++ b/test/test_layer.py
@@ -69,32 +69,32 @@ class TestBaseMap(unittest.TestCase):
         # ensure correct BaseMap urls are created
         # See URLs here: https://carto.com/location-data-services/basemaps/
         self.assertEqual(self.dark_map_all.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'dark_all/{z}/{x}/{y}.png')
         self.assertEqual(self.light_map_all.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'light_all/{z}/{x}/{y}.png')
         self.assertEqual(self.voyager_labels_under.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
-                         'rastertiles/voyager_labels_under/{z}/{x}/{y}.png')
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
+                         'voyager_labels_under/{z}/{x}/{y}.png')
         self.assertEqual(self.dark_map_no_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'dark_nolabels/{z}/{x}/{y}.png')
         self.assertEqual(self.light_map_no_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'light_nolabels/{z}/{x}/{y}.png')
         self.assertEqual(self.voyager_map_no_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
-                         'rastertiles/voyager_nolabels/{z}/{x}/{y}.png')
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
+                         'voyager_nolabels/{z}/{x}/{y}.png')
         self.assertEqual(self.light_only_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'light_only_labels/{z}/{x}/{y}.png')
         self.assertEqual(self.dark_only_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
                          'dark_only_labels/{z}/{x}/{y}.png')
         self.assertEqual(self.voyager_only_labels.url,
-                         'https://cartodb-basemaps-{s}.global.ssl.fastly.net/'
-                         'rastertiles/voyager_only_labels/{z}/{x}/{y}.png')
+                         'https://{s}.basemaps.cartocdn.com/rastertiles/'
+                         'voyager_only_labels/{z}/{x}/{y}.png')
 
         # ensure self.is_basic() works as intended
         self.assertTrue(self.light_map_all.is_basic(),
diff --git a/test/test_maps.py b/test/test_maps.py
index 1e3819ce..429feac2 100644
--- a/test/test_maps.py
+++ b/test/test_maps.py
@@ -62,111 +62,110 @@ class TestMaps(unittest.TestCase):
         map_name = get_map_name(self.layers,
                                 has_zoom=False)
         self.assertEqual(
-                map_name,
-                'cartoframes_ver20170406_layers2_time0_baseid1_labels0_zoom0')
+            map_name,
+            'cartoframes_ver20170406_layers2_time0_baseid1_labels0_zoom0')
         self.assertEqual(
-                get_map_name(self.layers, has_zoom=True),
-                'cartoframes_ver20170406_layers2_time0_baseid1_labels0_zoom1')
+            get_map_name(self.layers, has_zoom=True),
+            'cartoframes_ver20170406_layers2_time0_baseid1_labels0_zoom1')
         self.assertEqual(
-                get_map_name(self.layers_w_time, has_zoom=False),
-                'cartoframes_ver20170406_layers3_time1_baseid1_labels1_zoom0')
+            get_map_name(self.layers_w_time, has_zoom=False),
+            'cartoframes_ver20170406_layers3_time1_baseid1_labels1_zoom0')
 
     def test_map_template(self):
         """maps.map_template_dict"""
         map_template = get_map_template(self.layers, has_zoom=False)
-        js = {
-                "placeholders": {
-                    "north": {
-                        "default": 45,
-                        "type": "number"
-                        },
-                    "cartocss_1": {
-                        "default": ("#layer { "
-                                    "marker-fill: red; "
-                                    "marker-width: 5; "
-                                    "marker-allow-overlap: true; "
-                                    "marker-line-color: #000; "
-                                    "}"),
-                        "type": "sql_ident"
-                        },
-                    "cartocss_0": {
-                        "default": ("#layer { "
-                                    "marker-fill: red; "
-                                    "marker-width: 5; "
-                                    "marker-allow-overlap: true; "
-                                    "marker-line-color: #000; }"),
-                        "type": "sql_ident"
-                        },
-                    "west": {
-                        "default": -45,
-                        "type": "number"
-                        },
-                    "east": {
-                        "default": 45,
-                        "type": "number"
-                        },
-                    "sql_0": {
-                        "default": ("SELECT ST_PointFromText('POINT(0 0)', "
-                                    "4326) AS the_geom, 1 AS cartodb_id, "
-                                    "ST_PointFromText('Point(0 0)', 3857) AS "
-                                    "the_geom_webmercator"),
-                        "type": "sql_ident"
-                        },
-                    "sql_1": {
-                        "default": ("SELECT ST_PointFromText('POINT(0 0)', "
-                                    "4326) AS the_geom, 1 AS cartodb_id, "
-                                    "ST_PointFromText('Point(0 0)', 3857) AS "
-                                    "the_geom_webmercator"),
-                        "type": "sql_ident"
-                        },
-                    "south": {
-                        "default": -45,
-                        "type": "number"
+        filledtemplate = {
+            "placeholders": {
+                "north": {
+                    "default": 45,
+                    "type": "number"
+                },
+                "cartocss_1": {
+                    "default": ("#layer { "
+                                "marker-fill: red; "
+                                "marker-width: 5; "
+                                "marker-allow-overlap: true; "
+                                "marker-line-color: #000; "
+                                "}"),
+                    "type": "sql_ident"
+                },
+                "cartocss_0": {
+                    "default": ("#layer { "
+                                "marker-fill: red; "
+                                "marker-width: 5; "
+                                "marker-allow-overlap: true; "
+                                "marker-line-color: #000; }"),
+                    "type": "sql_ident"
+                },
+                "west": {
+                    "default": -45,
+                    "type": "number"
+                },
+                "east": {
+                    "default": 45,
+                    "type": "number"
+                },
+                "sql_0": {
+                    "default": ("SELECT ST_PointFromText('POINT(0 0)', "
+                                "4326) AS the_geom, 1 AS cartodb_id, "
+                                "ST_PointFromText('Point(0 0)', 3857) AS "
+                                "the_geom_webmercator"),
+                    "type": "sql_ident"
+                },
+                "sql_1": {
+                    "default": ("SELECT ST_PointFromText('POINT(0 0)', "
+                                "4326) AS the_geom, 1 AS cartodb_id, "
+                                "ST_PointFromText('Point(0 0)', 3857) AS "
+                                "the_geom_webmercator"),
+                    "type": "sql_ident"
+                },
+                "south": {
+                    "default": -45,
+                    "type": "number"
+                    }
+                },
+            "version": "0.0.1",
+            "name": ("cartoframes_ver20170406_layers2_time0_baseid1_"
+                     "labels0_zoom0"),
+            "layergroup": {
+                "layers": [
+                    {
+                        "type": "http",
+                        "options": {
+                            "urlTemplate": ("https://{s}.basemaps."
+                                            "cartocdn.com/rastertiles"
+                                            "/dark_all/{z}/{x}/{y}."
+                                            "png"),
+                            "subdomains": "abcd"
                         }
                     },
-                "version": "0.0.1",
-                "name": ("cartoframes_ver20170406_layers2_time0_baseid1_"
-                         "labels0_zoom0"),
-                "layergroup": {
-                        "layers": [
-                            {
-                                "type": "http",
-                                "options": {
-                                    "urlTemplate": ("https://cartodb-basemaps-"
-                                                    "{s}.global.ssl.fastly.net"
-                                                    "/dark_all/{z}/{x}/{y}."
-                                                    "png"),
-                                    "subdomains": "abcd"
-                                    }
-                                },
-                            {
-                                "type": "mapnik",
-                                "options": {
-                                    "cartocss": "<%= cartocss_0 %>",
-                                    "sql": "<%= sql_0 %>",
-                                    "cartocss_version": "2.1.1"
-                                    }
-                                },
-                            {
-                                "type": "mapnik",
-                                "options": {
-                                    "cartocss": "<%= cartocss_1 %>",
-                                    "sql": "<%= sql_1 %>",
-                                    "cartocss_version": "2.1.1"
-                                    }
-                                }
-                            ],
-                        "version": "1.0.1"
-                        },
-                "view": {
-                        "bounds": {
-                            "west": "<%= west %>",
-                            "east": "<%= east %>",
-                            "north": "<%= north %>",
-                            "south": "<%= south %>"
-                            }
+                    {
+                        "type": "mapnik",
+                        "options": {
+                            "cartocss": "<%= cartocss_0 %>",
+                            "sql": "<%= sql_0 %>",
+                            "cartocss_version": "2.1.1"
                         }
+                    },
+                    {
+                        "type": "mapnik",
+                        "options": {
+                            "cartocss": "<%= cartocss_1 %>",
+                            "sql": "<%= sql_1 %>",
+                            "cartocss_version": "2.1.1"
+                        }
+                    }],
+                "version": "1.0.1"
+            },
+            "view": {
+                "bounds": {
+                    "west": "<%= west %>",
+                    "east": "<%= east %>",
+                    "north": "<%= north %>",
+                    "south": "<%= south %>"
                 }
+            }
+        }
 
         map_template_dict = json.loads(map_template)
-        self.assertDictEqual(map_template_dict, js)
+        self.assertDictEqual(map_template_dict, filledtemplate)

pip install -e .
parse_log_pytest
requirements.txt
pytest shapely coveralls
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
appdirs==1.4.4
attrs==22.2.0
Babel==2.11.0
backcall==0.2.0
carto==1.11.3
-e git+https://github.com/CartoDB/cartoframes.git@86069f44058986062a2af21ef1f6690864784596#egg=cartoframes
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
coveralls==3.3.1
decorator==5.1.1
docopt==0.6.2
docutils==0.18.1
future==1.0.0
idna==3.10
imagesize==1.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
ipython==7.16.3
ipython-genutils==0.2.0
jedi==0.17.2
Jinja2==3.0.3
MarkupSafe==2.0.1
numpy==1.19.5
packaging==21.3
pandas==1.1.5
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
pluggy==1.0.0
pockets==0.9.1
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
Pygments==2.14.0
pyparsing==3.1.4
pyrestcli==0.6.11
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
Shapely==1.8.5.post1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-napoleon==0.7
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tomli==1.2.3
tqdm==4.64.1
traitlets==4.3.3
typing_extensions==4.1.1
urllib3==1.26.20
wcwidth==0.2.13
webcolors==1.7
zipp==3.6.0

name: cartoframes
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - appdirs==1.4.4
      - attrs==22.2.0
      - babel==2.11.0
      - backcall==0.2.0
      - carto==1.11.3
      - charset-normalizer==2.0.12
      - coverage==6.2
      - coveralls==3.3.1
      - decorator==5.1.1
      - docopt==0.6.2
      - docutils==0.18.1
      - future==1.0.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - jedi==0.17.2
      - jinja2==3.0.3
      - markupsafe==2.0.1
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pluggy==1.0.0
      - pockets==0.9.1
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pyrestcli==0.6.11
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - shapely==1.8.5.post1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-napoleon==0.7
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tomli==1.2.3
      - tqdm==4.64.1
      - traitlets==4.3.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - wcwidth==0.2.13
      - webcolors==1.7
      - zipp==3.6.0
prefix: /opt/conda/envs/cartoframes

test/test_layer.py::TestBaseMap::test_basemap_source test/test_maps.py::TestMaps::test_map_template
test/test_layer.py::TestAbstractLayer::test_class test/test_layer.py::TestLayer::test_layer_setup_dataframe test/test_layer.py::TestBaseMap::test_basemap_invalid test/test_layer.py::TestQueryLayer::test_querylayer_colors test/test_layer.py::TestQueryLayer::test_querylayer_get_cartocss test/test_layer.py::TestQueryLayer::test_querylayer_size_and_time test/test_layer.py::TestQueryLayer::test_querylayer_size_column_key test/test_layer.py::TestQueryLayer::test_querylayer_size_default test/test_layer.py::TestQueryLayer::test_querylayer_size_defaults test/test_layer.py::TestQueryLayer::test_querylayer_time_category test/test_layer.py::TestQueryLayer::test_querylayer_time_default test/test_layer.py::TestQueryLayer::test_querylayer_time_errors test/test_layer.py::TestQueryLayer::test_querylayer_time_numeric test/test_maps.py::TestMaps::test_get_map_name test/test_maps.py::TestMaps::test_has_time_layer test/test_maps.py::TestMaps::test_non_basemap_layers
cartoframes/layer.py
cartoframes/layer.py