Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	Local use usage
Browse files- .env.example +7 -1
- middlewares/checkUser.js +3 -0
- server.js +24 -14
- src/components/deploy-button/deploy-button.tsx +31 -24
- src/components/settings/settings.tsx +9 -0
- utils/types.ts +1 -0
    	
        .env.example
    CHANGED
    
    | @@ -2,4 +2,10 @@ OAUTH_CLIENT_ID= | |
| 2 | 
             
            OAUTH_CLIENT_SECRET=
         | 
| 3 | 
             
            APP_PORT=5173
         | 
| 4 | 
             
            REDIRECT_URI=http://localhost:5173/auth/login
         | 
| 5 | 
            -
            DEFAULT_HF_TOKEN=
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 2 | 
             
            OAUTH_CLIENT_SECRET=
         | 
| 3 | 
             
            APP_PORT=5173
         | 
| 4 | 
             
            REDIRECT_URI=http://localhost:5173/auth/login
         | 
| 5 | 
            +
            DEFAULT_HF_TOKEN=
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # Optional
         | 
| 8 | 
            +
            # By setting this variable, you will bypass the login page + the free requests
         | 
| 9 | 
            +
            # and will use the token directly.
         | 
| 10 | 
            +
            # This is useful for testing purposes or local use.
         | 
| 11 | 
            +
            HF_TOKEN=
         | 
    	
        middlewares/checkUser.js
    CHANGED
    
    | @@ -1,4 +1,7 @@ | |
| 1 | 
             
            export default async function checkUser(req, res, next) {
         | 
|  | |
|  | |
|  | |
| 2 | 
             
              const { hf_token } = req.cookies;
         | 
| 3 | 
             
              if (!hf_token) {
         | 
| 4 | 
             
                return res.status(401).send({
         | 
|  | |
| 1 | 
             
            export default async function checkUser(req, res, next) {
         | 
| 2 | 
            +
              if (process.env.HF_TOKEN && process.env.HF_TOKEN !== "") {
         | 
| 3 | 
            +
                return next();
         | 
| 4 | 
            +
              }
         | 
| 5 | 
             
              const { hf_token } = req.cookies;
         | 
| 6 | 
             
              if (!hf_token) {
         | 
| 7 | 
             
                return res.status(401).send({
         | 
    	
        server.js
    CHANGED
    
    | @@ -42,11 +42,6 @@ const getPTag = (repoId) => { | |
| 42 | 
             
            };
         | 
| 43 |  | 
| 44 | 
             
            app.get("/api/login", (_req, res) => {
         | 
| 45 | 
            -
              // res.redirect(
         | 
| 46 | 
            -
              //   302,
         | 
| 47 | 
            -
              //   `https://huggingface.co/oauth/authorize?client_id=${process.env.OAUTH_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=openid%20profile%20write-repos%20manage-repos%20inference-api&prompt=consent&state=1234567890`
         | 
| 48 | 
            -
              // );
         | 
| 49 | 
            -
              // redirect in new tab
         | 
| 50 | 
             
              const redirectUrl = `https://huggingface.co/oauth/authorize?client_id=${process.env.OAUTH_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=openid%20profile%20write-repos%20manage-repos%20inference-api&prompt=consent&state=1234567890`;
         | 
| 51 | 
             
              res.status(200).send({
         | 
| 52 | 
             
                ok: true,
         | 
| @@ -101,7 +96,15 @@ app.get("/auth/logout", (req, res) => { | |
| 101 | 
             
            });
         | 
| 102 |  | 
| 103 | 
             
            app.get("/api/@me", checkUser, async (req, res) => {
         | 
| 104 | 
            -
               | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 105 | 
             
              try {
         | 
| 106 | 
             
                const request_user = await fetch("https://huggingface.co/oauth/userinfo", {
         | 
| 107 | 
             
                  headers: {
         | 
| @@ -133,7 +136,11 @@ app.post("/api/deploy", checkUser, async (req, res) => { | |
| 133 | 
             
                });
         | 
| 134 | 
             
              }
         | 
| 135 |  | 
| 136 | 
            -
               | 
|  | |
|  | |
|  | |
|  | |
| 137 | 
             
              try {
         | 
| 138 | 
             
                const repo = {
         | 
| 139 | 
             
                  type: "space",
         | 
| @@ -211,6 +218,11 @@ app.post("/api/ask-ai", async (req, res) => { | |
| 211 |  | 
| 212 | 
             
              const { hf_token } = req.cookies;
         | 
| 213 | 
             
              let token = hf_token;
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
| 214 | 
             
              const ip =
         | 
| 215 | 
             
                req.headers["x-forwarded-for"]?.split(",")[0].trim() ||
         | 
| 216 | 
             
                req.headers["x-real-ip"] ||
         | 
| @@ -244,12 +256,6 @@ app.post("/api/ask-ai", async (req, res) => { | |
| 244 | 
             
              if (html) TOKENS_USED += html.length;
         | 
| 245 |  | 
| 246 | 
             
              const DEFAULT_PROVIDER = PROVIDERS.novita;
         | 
| 247 | 
            -
              // const selectedProvider =
         | 
| 248 | 
            -
              //   provider === "auto"
         | 
| 249 | 
            -
              //     ? TOKENS_USED < PROVIDERS.sambanova.max_tokens
         | 
| 250 | 
            -
              //       ? PROVIDERS.sambanova
         | 
| 251 | 
            -
              //       : DEFAULT_PROVIDER
         | 
| 252 | 
            -
              //     : PROVIDERS[provider] ?? DEFAULT_PROVIDER;
         | 
| 253 | 
             
              const selectedProvider =
         | 
| 254 | 
             
                provider === "auto"
         | 
| 255 | 
             
                  ? DEFAULT_PROVIDER
         | 
| @@ -355,7 +361,11 @@ app.get("/api/remix/:username/:repo", async (req, res) => { | |
| 355 | 
             
              const { username, repo } = req.params;
         | 
| 356 | 
             
              const { hf_token } = req.cookies;
         | 
| 357 |  | 
| 358 | 
            -
               | 
|  | |
|  | |
|  | |
|  | |
| 359 |  | 
| 360 | 
             
              const repoId = `${username}/${repo}`;
         | 
| 361 |  | 
|  | |
| 42 | 
             
            };
         | 
| 43 |  | 
| 44 | 
             
            app.get("/api/login", (_req, res) => {
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
| 45 | 
             
              const redirectUrl = `https://huggingface.co/oauth/authorize?client_id=${process.env.OAUTH_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=openid%20profile%20write-repos%20manage-repos%20inference-api&prompt=consent&state=1234567890`;
         | 
| 46 | 
             
              res.status(200).send({
         | 
| 47 | 
             
                ok: true,
         | 
|  | |
| 96 | 
             
            });
         | 
| 97 |  | 
| 98 | 
             
            app.get("/api/@me", checkUser, async (req, res) => {
         | 
| 99 | 
            +
              let { hf_token } = req.cookies;
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              if (process.env.HF_TOKEN && process.env.HF_TOKEN !== "") {
         | 
| 102 | 
            +
                return res.send({
         | 
| 103 | 
            +
                  preferred_username: "local-use",
         | 
| 104 | 
            +
                  isLocalUse: true,
         | 
| 105 | 
            +
                });
         | 
| 106 | 
            +
              }
         | 
| 107 | 
            +
             | 
| 108 | 
             
              try {
         | 
| 109 | 
             
                const request_user = await fetch("https://huggingface.co/oauth/userinfo", {
         | 
| 110 | 
             
                  headers: {
         | 
|  | |
| 136 | 
             
                });
         | 
| 137 | 
             
              }
         | 
| 138 |  | 
| 139 | 
            +
              let { hf_token } = req.cookies;
         | 
| 140 | 
            +
              if (process.env.HF_TOKEN && process.env.HF_TOKEN !== "") {
         | 
| 141 | 
            +
                hf_token = process.env.HF_TOKEN;
         | 
| 142 | 
            +
              }
         | 
| 143 | 
            +
             | 
| 144 | 
             
              try {
         | 
| 145 | 
             
                const repo = {
         | 
| 146 | 
             
                  type: "space",
         | 
|  | |
| 218 |  | 
| 219 | 
             
              const { hf_token } = req.cookies;
         | 
| 220 | 
             
              let token = hf_token;
         | 
| 221 | 
            +
             | 
| 222 | 
            +
              if (process.env.HF_TOKEN && process.env.HF_TOKEN !== "") {
         | 
| 223 | 
            +
                hf_token = process.env.HF_TOKEN;
         | 
| 224 | 
            +
              }
         | 
| 225 | 
            +
             | 
| 226 | 
             
              const ip =
         | 
| 227 | 
             
                req.headers["x-forwarded-for"]?.split(",")[0].trim() ||
         | 
| 228 | 
             
                req.headers["x-real-ip"] ||
         | 
|  | |
| 256 | 
             
              if (html) TOKENS_USED += html.length;
         | 
| 257 |  | 
| 258 | 
             
              const DEFAULT_PROVIDER = PROVIDERS.novita;
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 259 | 
             
              const selectedProvider =
         | 
| 260 | 
             
                provider === "auto"
         | 
| 261 | 
             
                  ? DEFAULT_PROVIDER
         | 
|  | |
| 361 | 
             
              const { username, repo } = req.params;
         | 
| 362 | 
             
              const { hf_token } = req.cookies;
         | 
| 363 |  | 
| 364 | 
            +
              let token = hf_token || process.env.DEFAULT_HF_TOKEN;
         | 
| 365 | 
            +
             | 
| 366 | 
            +
              if (process.env.HF_TOKEN && process.env.HF_TOKEN !== "") {
         | 
| 367 | 
            +
                token = process.env.HF_TOKEN;
         | 
| 368 | 
            +
              }
         | 
| 369 |  | 
| 370 | 
             
              const repoId = `${username}/${repo}`;
         | 
| 371 |  | 
    	
        src/components/deploy-button/deploy-button.tsx
    CHANGED
    
    | @@ -84,31 +84,38 @@ function DeployButton({ | |
| 84 | 
             
                <div className="flex items-center justify-end gap-5">
         | 
| 85 | 
             
                  <LoadButton auth={auth} setHtml={setHtml} setPath={setPath} />
         | 
| 86 | 
             
                  <div className="relative flex items-center justify-end">
         | 
| 87 | 
            -
                    {auth && | 
| 88 | 
            -
                       | 
| 89 | 
            -
                         | 
| 90 | 
            -
                          className="mr- | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
                           | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
                             | 
| 104 | 
            -
                            target="_blank"
         | 
| 105 | 
            -
                            className="underline hover:text-white"
         | 
| 106 | 
             
                          >
         | 
| 107 | 
            -
                             | 
| 108 | 
            -
                          </ | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 112 | 
             
                    <button
         | 
| 113 | 
             
                      className={classNames(
         | 
| 114 | 
             
                        "relative cursor-pointer flex-none flex items-center justify-center rounded-md text-xs lg:text-sm font-semibold leading-5 lg:leading-6 py-1.5 px-5 hover:bg-pink-400 text-white shadow-sm dark:shadow-highlight/20",
         | 
|  | |
| 84 | 
             
                <div className="flex items-center justify-end gap-5">
         | 
| 85 | 
             
                  <LoadButton auth={auth} setHtml={setHtml} setPath={setPath} />
         | 
| 86 | 
             
                  <div className="relative flex items-center justify-end">
         | 
| 87 | 
            +
                    {auth &&
         | 
| 88 | 
            +
                      (auth.isLocalUse ? (
         | 
| 89 | 
            +
                        <>
         | 
| 90 | 
            +
                          <div className="bg-amber-500/10 border border-amber-10 text-amber-500 font-semibold leading-5 lg:leading-6 py-1 px-5 text-xs lg:text-sm rounded-md mr-4 select-none">
         | 
| 91 | 
            +
                            Local Usage
         | 
| 92 | 
            +
                          </div>
         | 
| 93 | 
            +
                        </>
         | 
| 94 | 
            +
                      ) : (
         | 
| 95 | 
            +
                        <>
         | 
| 96 | 
            +
                          <button
         | 
| 97 | 
            +
                            className="mr-2 cursor-pointer"
         | 
| 98 | 
            +
                            onClick={() => {
         | 
| 99 | 
            +
                              if (confirm("Are you sure you want to log out?")) {
         | 
| 100 | 
            +
                                // go to /auth/logout page
         | 
| 101 | 
            +
                                window.location.href = "/auth/logout";
         | 
| 102 | 
            +
                              }
         | 
| 103 | 
            +
                            }}
         | 
|  | |
|  | |
| 104 | 
             
                          >
         | 
| 105 | 
            +
                            <FaPowerOff className="text-lg text-red-500" />
         | 
| 106 | 
            +
                          </button>
         | 
| 107 | 
            +
                          <p className="mr-3 text-xs lg:text-sm text-gray-300">
         | 
| 108 | 
            +
                            <span className="max-lg:hidden">Connected as </span>
         | 
| 109 | 
            +
                            <a
         | 
| 110 | 
            +
                              href={`https://huggingface.co/${auth.preferred_username}`}
         | 
| 111 | 
            +
                              target="_blank"
         | 
| 112 | 
            +
                              className="underline hover:text-white"
         | 
| 113 | 
            +
                            >
         | 
| 114 | 
            +
                              {auth.preferred_username}
         | 
| 115 | 
            +
                            </a>
         | 
| 116 | 
            +
                          </p>
         | 
| 117 | 
            +
                        </>
         | 
| 118 | 
            +
                      ))}
         | 
| 119 | 
             
                    <button
         | 
| 120 | 
             
                      className={classNames(
         | 
| 121 | 
             
                        "relative cursor-pointer flex-none flex items-center justify-center rounded-md text-xs lg:text-sm font-semibold leading-5 lg:leading-6 py-1.5 px-5 hover:bg-pink-400 text-white shadow-sm dark:shadow-highlight/20",
         | 
    	
        src/components/settings/settings.tsx
    CHANGED
    
    | @@ -54,6 +54,15 @@ function Settings({ | |
| 54 | 
             
                    <main className="px-4 pt-3 pb-4 space-y-4">
         | 
| 55 | 
             
                      {/* toggle using tailwind css */}
         | 
| 56 | 
             
                      <div>
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 57 | 
             
                        <div className="flex items-center justify-between">
         | 
| 58 | 
             
                          <p className="text-gray-800 text-sm font-medium flex items-center justify-between">
         | 
| 59 | 
             
                            Use auto-provider
         | 
|  | |
| 54 | 
             
                    <main className="px-4 pt-3 pb-4 space-y-4">
         | 
| 55 | 
             
                      {/* toggle using tailwind css */}
         | 
| 56 | 
             
                      <div>
         | 
| 57 | 
            +
                        <a
         | 
| 58 | 
            +
                          href="/"
         | 
| 59 | 
            +
                          className="w-full flex items-center justify-between text-gray-600 bg-gray-50 border border-gray-100 px-2 py-2 rounded-lg mb-3 text-sm font-medium hover:brightness-95"
         | 
| 60 | 
            +
                        >
         | 
| 61 | 
            +
                          How to use it locally?
         | 
| 62 | 
            +
                          <button className="bg-black text-white rounded-md px-3 py-1.5 text-xs font-semibold cursor-pointer">
         | 
| 63 | 
            +
                            See the guide
         | 
| 64 | 
            +
                          </button>
         | 
| 65 | 
            +
                        </a>
         | 
| 66 | 
             
                        <div className="flex items-center justify-between">
         | 
| 67 | 
             
                          <p className="text-gray-800 text-sm font-medium flex items-center justify-between">
         | 
| 68 | 
             
                            Use auto-provider
         | 
    	
        utils/types.ts
    CHANGED
    
    | @@ -2,4 +2,5 @@ export interface Auth { | |
| 2 | 
             
              preferred_username: string;
         | 
| 3 | 
             
              picture: string;
         | 
| 4 | 
             
              name: string;
         | 
|  | |
| 5 | 
             
            }
         | 
|  | |
| 2 | 
             
              preferred_username: string;
         | 
| 3 | 
             
              picture: string;
         | 
| 4 | 
             
              name: string;
         | 
| 5 | 
            +
              isLocalUse?: boolean;
         | 
| 6 | 
             
            }
         |