Repository: huggingface/huggingface_hub
Pull request #445 (2021-10-28 13:21:04)

Make widgetinputsamples wider & rounded
CSS style update for WidgetInputSamples.svelte
1. Rounded outline
2. Wider

<img width="532" alt="Screenshot 2021-10-28 at 15 18 40" src="https://user-images.githubusercontent.com/11827707/139263842-059ac161-c443-4a5f-af2e-442f7b76bf72.png">

Checkout demo [here](https://617aa41f47f6b43722756eeb--huggingface-widgets.netlify.app/bigscience/T0pp)


Patch:
diff --git a/docs/hub/spaces.md b/docs/hub/spaces.md
index 99482c8d..9c934f84 100644
--- a/docs/hub/spaces.md
+++ b/docs/hub/spaces.md
@@ -4,29 +4,21 @@ title: Documentation for Spaces
 
 <h1>How to get started with Spaces</h1>
 
-<div class="p-4 border border-gray-200 rounded-lg">
-	⚠️ This feature is currently in private beta, <a style="font-weight: bold !important" href="/spaces">sign up to the waiting list</a> or <a href="#how-can-i-contact-you">reach out to us</a> if you'd like to try it out ⚠️
-</div>
-
 ## What are Spaces?
 
-Spaces are a simple way to host ML demo apps directly on your profile or your organization’s  profile.
+Spaces are a simple way to host ML demo apps directly on your profile or your organization’s  profile. This allows you to create your ML portfolio, showcase your projects at conferences or to stakeholders, and work collaboratively with other people in the ML ecosystem.
 
 We support two awesome SDKs that let you build cool apps in Python in a matter of minutes: **[Streamlit](https://streamlit.io/)** and **[Gradio](https://gradio.app/)**.
 
-**To get started**, simply click on [New Space](https://huggingface.co/new-space) in the top navigation menu, create a new repo of type `Space`, and pick your SDK:
-
-![/docs/assets/hub/new-space.gif](/docs/assets/hub/new-space.gif)
-
-Under the hood, we store your code inside a git repository just as done for model and dataset repositories. Thanks to this, the same tools you're already used to (`git` and `git-lfs`) will also work for Spaces.
+<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/3bSVKNKb_PY" title="Spaces intro" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
 
-Each time you commit, we deploy a containerized version of your code on our Infra. More details below!
+**To get started**, simply click on [New Space](https://huggingface.co/new-space) in the top navigation menu, create a new repo of type `Space`, and pick your SDK.
 
-<!-- TODO(have someone record a Youtube demo of Spaces showcasing some cool apps already running, etc) -->
+Under the hood, Spaces stores your code inside a git repository, just like the model and dataset repositories. Thanks to this, the same tools you're already used to (`git` and `git-lfs`) also work for Spaces.
 
 ## Should I use Streamlit or Gradio?
 
-We recommend you try both as they're both really awesome! 😎
+We recommend you try both because they're really awesome! 😎
 
 Streamlit's documentation is at https://docs.streamlit.io/ and Gradio's doc is at https://gradio.app/getting_started.
 
@@ -78,26 +70,35 @@ We deploy a containerized version of your code on our Infra, each time you commi
 
 If your app needs any secret keys or tokens to run, you do not want to hardcode them inside your code! Instead, head over to the settings page of your Space repo, and you'll be able to input key/secret pairs.
 
-Those secrets will be exposed to your app using the [Streamlit Secrets](https://blog.streamlit.io/secrets-in-sharing-apps/) feature if it's a Streamlit app, or as env variables in other cases.
+Secrets will be exposed to your app using the [Streamlit Secrets](https://blog.streamlit.io/secrets-in-sharing-apps/) feature if it's a Streamlit app, or as environment variables in other cases.
 
-## Streamlit advanced features
 
-We support those Streamlit features transparently:
+## I am having issues with Streamlit versions!
 
-- `st.experimental_get_query_params()` and `st.experimental_set_query_params(**parameter)` to manage app state in the url
-- if something doesn't work, please [reach out](#how-can-i-contact-you).
+The Streamlit version is not configured in the `requirements.txt` file, but rather in the README metadata config through the `sdk_version` setting. Not all Streamlit versions are supported. Refer to the [reference section](#reference) for more information about which versions are supported.
 
-## I am having issues with Streamlit versions!
+## Can I use my own HTML instead of Streamlit or Gradio?
 
-The Streamlit version is not configured in the `requirements.txt` file, but in the README metadata config through the `sdk_version` setting. Note that we do not support all Streamlit versions, please refer to the [reference section](#reference) for more info on this.
+Although we strongly encourage you to use Streamlit and Gradio, you can also use your own HTML
+code by defining `sdk: static` and having the HTML within an `index.html` file. Here are some examples:
 
-## How can I contact you?
+* [Smarter NPC](https://huggingface.co/spaces/mishig/smarter_npc): Display a PlayCanvas project with an iframe.
+* [Huggingfab](https://huggingface.co/spaces/pierreant-p/huggingfab): Display a Sketchfab model in Spaces.
 
-Feel free to ask question in the [Forum](https://discuss.huggingface.co/) if it's suitable for the community.
+Please [get in touch](#how-can-i-contact-you) if you have an idea for cool static Spaces.
 
-If you're interested in infra challenges, custom demos, GPU or something else, please reach out to us by sending an email to website at huggingface.co.
 
-You can also tag us [on Twitter](https://twitter.com/huggingface)!
+## Building an organization card
+
+Create an organization card to help users learn more about what your organization is working on and how users can use your libraries, models, datasets, and Spaces. Build an organization card by creating a static README Space with HTML. As an example, take a look at the [Amazon](https://huggingface.co/spaces/amazon/README/blob/main/README.md) and [spaCy](https://huggingface.co/spaces/spacy/README/blob/main/README.md) organization cards.
+
+* https://huggingface.co/spaces/spacy/README/blob/main/README.md
+* https://huggingface.co/spaces/amazon/README/blob/main/README.md
+
+
+## Can I use Bokeh?
+
+Streamlit has built-in support for Bokeh with the `st.bokeh_chart` component.
 
 ## How should I link my Spaces demo in my GitHub repo?
 
@@ -157,7 +158,7 @@ Color for Thumbnail gradient (red, yellow, green, blue, indigo, purple, pink, gr
 Color for Thumbnail gradient (red, yellow, green, blue, indigo, purple, pink, gray)
 
 **`sdk`** : _string_  
-Can be either `gradio` or `streamlit`
+Can be either `gradio`, `streamlit` or `static`
 
 **`sdk_version`** : _string_  
 Only applicable for `streamlit` SDK. Currently available versions are :  
@@ -170,10 +171,9 @@ Path is relative to the root of the repository.
 **`pinned`** : _boolean_  
 Whether the Space stays on top of your list.
 
-
 ## How can I manage my app through Github
 
-You can keep your app in sync with your GitHub repository by leveraging GitHub Actions:
+Keep your app in sync with your GitHub repository with GitHub Actions:
 
 - We require Git LFS for files above 10MB so you may need to review your files if you don't want to use Git LFS. This includes your history. You can use handy tools such as [BFG Repo-Cleaner](https://rtyley.github.io/bfg-repo-cleaner/) to remove the large files from your history (keep a local copy of your repository for backup).
 - Set your GitHub repository and your Spaces app initially in sync: to add your Spaces app as an additional remote to your existing git repository, you can use the command `git remote add space https://huggingface.co/spaces/FULL_SPACE_NAME`. You can then force-push to sync everything for the first time: `git push --force space main`
@@ -225,6 +225,14 @@ jobs:
 
 ```
 
+## How can I contact you?
+
+Feel free to ask questions on the [forum](https://discuss.huggingface.co/) if it's suitable for the community.
+
+If you're interested in infra challenges, custom demos, GPUs, or something else, please reach out to us by sending an email to **website at huggingface.co**.
+
+You can also tag us [on Twitter](https://twitter.com/huggingface)!
+
 ## Changelog
 
 #### [2021-10-20] - Add support for Streamlit 1.0
diff --git a/src/huggingface_hub/commands/user.py b/src/huggingface_hub/commands/user.py
index 078b163d..a337d6e8 100644
--- a/src/huggingface_hub/commands/user.py
+++ b/src/huggingface_hub/commands/user.py
@@ -18,7 +18,11 @@ from getpass import getpass
 from typing import List, Union
 
 from huggingface_hub.commands import BaseHuggingfaceCLICommand
-from huggingface_hub.constants import REPO_TYPES, REPO_TYPES_URL_PREFIXES
+from huggingface_hub.constants import (
+    REPO_TYPES,
+    REPO_TYPES_URL_PREFIXES,
+    SPACES_SDK_TYPES,
+)
 from huggingface_hub.hf_api import HfApi, HfFolder
 from requests.exceptions import HTTPError
 
@@ -68,6 +72,12 @@ class UserCommands(BaseHuggingfaceCLICommand):
         repo_create_parser.add_argument(
             "--organization", type=str, help="Optional: organization namespace."
         )
+        repo_create_parser.add_argument(
+            "--space_sdk",
+            type=str,
+            help='Optional: Hugging Face Spaces SDK type. Required when --type is set to "space".',
+            choices=SPACES_SDK_TYPES,
+        )
         repo_create_parser.add_argument(
             "-y",
             "--yes",
@@ -263,6 +273,7 @@ class RepoCreateCommand(BaseUserCommand):
                 token=token,
                 organization=self.args.organization,
                 repo_type=self.args.type,
+                space_sdk=self.args.space_sdk,
             )
         except HTTPError as e:
             print(e)
diff --git a/src/huggingface_hub/constants.py b/src/huggingface_hub/constants.py
index f6c8ff0e..85536073 100644
--- a/src/huggingface_hub/constants.py
+++ b/src/huggingface_hub/constants.py
@@ -32,6 +32,7 @@ HUGGINGFACE_CO_URL_TEMPLATE = ENDPOINT + "/{repo_id}/resolve/{revision}/{filenam
 REPO_TYPE_DATASET = "dataset"
 REPO_TYPE_SPACE = "space"
 REPO_TYPES = [None, REPO_TYPE_DATASET, REPO_TYPE_SPACE]
+SPACES_SDK_TYPES = ["gradio", "streamlit", "static"]
 
 REPO_TYPES_URL_PREFIXES = {
     REPO_TYPE_DATASET: "datasets/",
diff --git a/src/huggingface_hub/hf_api.py b/src/huggingface_hub/hf_api.py
index fdbdf0e0..6264994e 100644
--- a/src/huggingface_hub/hf_api.py
+++ b/src/huggingface_hub/hf_api.py
@@ -26,7 +26,13 @@ from typing import IO, Dict, Iterable, List, Optional, Tuple, Union
 import requests
 from requests.exceptions import HTTPError
 
-from .constants import ENDPOINT, REPO_TYPES, REPO_TYPES_MAPPING, REPO_TYPES_URL_PREFIXES
+from .constants import (
+    ENDPOINT,
+    REPO_TYPES,
+    REPO_TYPES_MAPPING,
+    REPO_TYPES_URL_PREFIXES,
+    SPACES_SDK_TYPES,
+)
 
 
 if sys.version_info >= (3, 8):
@@ -35,7 +41,7 @@ else:
     from typing_extensions import Literal
 
 
-REMOTE_FILEPATH_REGEX = re.compile(r"^\w[\w\/]*(\.\w+)?$")
+REMOTE_FILEPATH_REGEX = re.compile(r"^\w[\w\/\-]*(\.\w+)?$")
 # ^^ No trailing slash, no backslash, no spaces, no relative parts ("." or "..")
 #    Only word characters and an optional extension
 
@@ -584,13 +590,24 @@ class HfApi:
         self,
         repo_id: str,
         revision: Optional[str] = None,
+        repo_type: Optional[str] = None,
         token: Optional[str] = None,
         timeout: Optional[float] = None,
-    ) -> ModelInfo:
+    ) -> List[str]:
         """
         Get the list of files in a given repo.
         """
-        info = self.model_info(repo_id, revision=revision, token=token, timeout=timeout)
+        if repo_type is None:
+            info = self.model_info(
+                repo_id, revision=revision, token=token, timeout=timeout
+            )
+        elif repo_type == "dataset":
+            info = self.dataset_info(
+                repo_id, revision=revision, token=token, timeout=timeout
+            )
+        else:
+            raise ValueError("Spaces are not available yet.")
+
         return [f.rfilename for f in info.siblings]
 
     def list_repos_objs(
@@ -664,6 +681,7 @@ class HfApi:
         repo_type: Optional[str] = None,
         exist_ok=False,
         lfsmultipartthresh: Optional[int] = None,
+        space_sdk: Optional[str] = None,
     ) -> str:
         """
         HuggingFace git-based system, used for models, datasets, and spaces.
@@ -679,6 +697,8 @@ class HfApi:
 
             lfsmultipartthresh: Optional: internal param for testing purposes.
 
+            space_sdk: Choice of SDK to use if repo_type is "space". Can be "streamlit", "gradio", or "static".
+
         Returns:
             URL to the newly created repo.
         """
@@ -707,6 +727,22 @@ class HfApi:
         json = {"name": name, "organization": organization, "private": private}
         if repo_type is not None:
             json["type"] = repo_type
+            if repo_type == "space":
+                if space_sdk is None:
+                    raise ValueError(
+                        "No space_sdk provided. `create_repo` expects space_sdk to be one of "
+                        f"{SPACES_SDK_TYPES} when repo_type is 'space'`"
+                    )
+                if space_sdk not in SPACES_SDK_TYPES:
+                    raise ValueError(
+                        f"Invalid space_sdk. Please choose one of {SPACES_SDK_TYPES}."
+                    )
+                json["sdk"] = space_sdk
+        if space_sdk is not None and repo_type != "space":
+            warnings.warn(
+                "Ignoring provided space_sdk because repo_type is not 'space'."
+            )
+
         if lfsmultipartthresh is not None:
             json["lfsmultipartthresh"] = lfsmultipartthresh
         r = requests.post(
@@ -821,6 +857,7 @@ class HfApi:
             path_prefix += REPO_TYPES_URL_PREFIXES[repo_type]
 
         path = "{}{}/{}/settings".format(path_prefix, namespace, name)
+
         json = {"private": private}
 
         r = requests.put(
diff --git a/widgets/src/lib/InferenceWidget/shared/WidgetInputSamples/WidgetInputSamples.svelte b/widgets/src/lib/InferenceWidget/shared/WidgetInputSamples/WidgetInputSamples.svelte
index 12708167..2e33503c 100644
--- a/widgets/src/lib/InferenceWidget/shared/WidgetInputSamples/WidgetInputSamples.svelte
+++ b/widgets/src/lib/InferenceWidget/shared/WidgetInputSamples/WidgetInputSamples.svelte
@@ -11,7 +11,7 @@
 
 <!-- svelte-ignore a11y-no-onchange -->
 <select
-	class="border-none text-sm w-28 truncate dark:bg-gray-950"
+	class="text-sm py-1  w-32 lg:w-44 border border-gray-100 truncate dark:bg-gray-950 rounded"
 	on:change={onChange}
 >
 	<option selected disabled>Examples</option>
diff --git a/widgets/src/routes/index.svelte b/widgets/src/routes/index.svelte
index 39394eb5..f8db2a15 100644
--- a/widgets/src/routes/index.svelte
+++ b/widgets/src/routes/index.svelte
@@ -132,7 +132,7 @@
 			],
 		},
 		{
-			id: "google/t5-small-ssm-nq",
+			id: "bigscience/T0pp",
 			pipeline_tag: "text2text-generation",
 		},
 		{


Test patch:
diff --git a/tests/test_hf_api.py b/tests/test_hf_api.py
index 7e7b9374..8043285a 100644
--- a/tests/test_hf_api.py
+++ b/tests/test_hf_api.py
@@ -21,8 +21,14 @@ import time
 import unittest
 from io import BytesIO
 
+import pytest
+
 import requests
-from huggingface_hub.constants import REPO_TYPE_DATASET, REPO_TYPE_SPACE
+from huggingface_hub.constants import (
+    REPO_TYPE_DATASET,
+    REPO_TYPE_SPACE,
+    SPACES_SDK_TYPES,
+)
 from huggingface_hub.file_download import cached_download, hf_hub_download
 from huggingface_hub.hf_api import (
     DatasetInfo,
@@ -153,28 +159,46 @@ class HfApiEndpointsTest(HfApiCommonTestWithLogin):
             name=DATASET_REPO_NAME, token=self._token, repo_type=REPO_TYPE_DATASET
         )
 
-    @unittest.skip("skipped while spaces in beta")
     def test_create_update_and_delete_space_repo(self):
-        self._api.create_repo(
-            name=SPACE_REPO_NAME, token=self._token, repo_type=REPO_TYPE_SPACE
-        )
-        res = self._api.update_repo_visibility(
-            name=SPACE_REPO_NAME,
-            token=self._token,
-            private=True,
-            repo_type=REPO_TYPE_SPACE,
-        )
-        self.assertTrue(res["private"])
-        res = self._api.update_repo_visibility(
-            name=SPACE_REPO_NAME,
-            token=self._token,
-            private=False,
-            repo_type=REPO_TYPE_SPACE,
-        )
-        self.assertFalse(res["private"])
-        self._api.delete_repo(
-            name=SPACE_REPO_NAME, token=self._token, repo_type=REPO_TYPE_SPACE
-        )
+        with pytest.raises(ValueError, match=r"No space_sdk provided.*"):
+            self._api.create_repo(
+                token=self._token,
+                name=SPACE_REPO_NAME,
+                repo_type=REPO_TYPE_SPACE,
+                space_sdk=None,
+            )
+        with pytest.raises(ValueError, match=r"Invalid space_sdk.*"):
+            self._api.create_repo(
+                token=self._token,
+                name=SPACE_REPO_NAME,
+                repo_type=REPO_TYPE_SPACE,
+                space_sdk="asdfasdf",
+            )
+
+        for sdk in SPACES_SDK_TYPES:
+            self._api.create_repo(
+                name=SPACE_REPO_NAME,
+                token=self._token,
+                repo_type=REPO_TYPE_SPACE,
+                space_sdk=sdk,
+            )
+            res = self._api.update_repo_visibility(
+                name=SPACE_REPO_NAME,
+                token=self._token,
+                private=True,
+                repo_type=REPO_TYPE_SPACE,
+            )
+            self.assertTrue(res["private"])
+            res = self._api.update_repo_visibility(
+                name=SPACE_REPO_NAME,
+                token=self._token,
+                private=False,
+                repo_type=REPO_TYPE_SPACE,
+            )
+            self.assertFalse(res["private"])
+            self._api.delete_repo(
+                name=SPACE_REPO_NAME, token=self._token, repo_type=REPO_TYPE_SPACE
+            )
 
 
 class HfApiUploadFileTest(HfApiCommonTestWithLogin):